From fbf11aea9ae0b2471a9b47f2df1b5b2f1dffb0d0 Mon Sep 17 00:00:00 2001 From: Ivan Bondarev Date: Mon, 8 Feb 2021 20:30:22 +0100 Subject: [PATCH] fix #2437 --- .../PatternsDesugaringVisitor.cs | 5 +- TestSuite/errors/err0403.pas | 4 + .../TreeConversion/syntax_tree_visitor.cs | 42546 ++++++++-------- bin/Lng/Eng/SyntaxTreeVisitorsErrors.dat | 3 +- bin/Lng/Rus/SyntaxTreeVisitorsErrors.dat | 3 +- bin/Lng/Ukr/SyntaxTreeVisitorsErrors.dat | 1 + 6 files changed, 21286 insertions(+), 21276 deletions(-) create mode 100644 TestSuite/errors/err0403.pas diff --git a/SyntaxVisitors/PatternsVisitors/PatternsDesugaringVisitor.cs b/SyntaxVisitors/PatternsVisitors/PatternsDesugaringVisitor.cs index 888797e97..c0ff57161 100644 --- a/SyntaxVisitors/PatternsVisitors/PatternsDesugaringVisitor.cs +++ b/SyntaxVisitors/PatternsVisitors/PatternsDesugaringVisitor.cs @@ -327,7 +327,10 @@ namespace SyntaxVisitors.PatternsVisitors foreach (var x in l) x.Parent = stat.Parent; var stl = stat.Parent as statement_list; - stl.ReplaceInList(stat, l); + if (stl != null) + stl.ReplaceInList(stat, l); + else + throw new SyntaxVisitorError("EMBEDDED_STATEMENT_CANNOT_BE_A_DECLARATION", stat.source_context); } //} diff --git a/TestSuite/errors/err0403.pas b/TestSuite/errors/err0403.pas new file mode 100644 index 000000000..ca54741d3 --- /dev/null +++ b/TestSuite/errors/err0403.pas @@ -0,0 +1,4 @@ +begin + if true then + var res := (a is integer(var b)); +end. \ No newline at end of file diff --git a/TreeConverter/TreeConversion/syntax_tree_visitor.cs b/TreeConverter/TreeConversion/syntax_tree_visitor.cs index 993c464c8..94d62b260 100644 --- a/TreeConverter/TreeConversion/syntax_tree_visitor.cs +++ b/TreeConverter/TreeConversion/syntax_tree_visitor.cs @@ -1,19380 +1,19380 @@ -// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) -//Посетитель синтаксического дерева. -using System; -using System.Linq; -using System.Collections; -using System.Collections.Generic; -using PascalABCCompiler.SyntaxTree; -using PascalABCCompiler.TreeRealization; - -using SyntaxTreeBuilder = PascalABCCompiler.SyntaxTree.SyntaxTreeBuilder; -using SymTable = SymbolTable; -using array_const = PascalABCCompiler.TreeRealization.array_const; -using compiler_directive = PascalABCCompiler.TreeRealization.compiler_directive; -using empty_statement = PascalABCCompiler.TreeRealization.empty_statement; -using for_node = PascalABCCompiler.TreeRealization.for_node; -using goto_statement = PascalABCCompiler.TreeRealization.goto_statement; -using if_node = PascalABCCompiler.TreeRealization.if_node; -using labeled_statement = PascalABCCompiler.TreeRealization.labeled_statement; -using question_colon_expression = PascalABCCompiler.TreeRealization.question_colon_expression; -using repeat_node = PascalABCCompiler.TreeRealization.repeat_node; -using sizeof_operator = PascalABCCompiler.TreeRealization.sizeof_operator; -using typeof_operator = PascalABCCompiler.TreeRealization.typeof_operator; -using while_node = PascalABCCompiler.TreeRealization.while_node; -using TreeConverter.LambdaExpressions.Closure; -using TreeConverter.LambdaExpressions; - -namespace PascalABCCompiler.TreeConverter -{ - // Сахарный узел синтаксического дерева. Не генерируется автоматически, поскольку содержит ссылку на узел семантического дерева - // Нужен только при генерации синтаксических узлов на семантическом уровне, т.е. для синтаксического сахара -/* public class semantic_type_node : SyntaxTree.type_definition - { - public type_node type { get; set; } - public semantic_type_node(type_node t) - { - type = t; - } - }*/ - - public partial class syntax_tree_visitor : SyntaxTree.WalkingVisitorNew // SSM 02.01.17 менять на визитор с другим порядком обхода можно, но бессмысленно - // Порядок обхода не важен поскольку все узлы visit переопределяются - // SSM 02.01.17 Использование ReplaceStatement из BaseChangeVisitor плохо изучено - что-то не работает - // Поэтому используется явный Parent и ReplaceStatement из узла statement_list - { - public SymbolTable.PrimaryScope MainScope - { - get - { - var a = SymbolTable.ScopeTable.Where(s => (s.GetType() == typeof(SymbolTable.UnitInterfaceScope))).Skip(1); - return new SymbolTable.PrimaryScope(a.Last()); - } - } - - public SymbolTable.PrimaryScope CurrentScope - { - get - { - if(context.CurrentScope != null) - return new SymbolTable.PrimaryScope(context.CurrentScope); - return null; - } - } - - public convertion_data_and_alghoritms convertion_data_and_alghoritms; - - internal returner ret; - - internal document current_document; - - public compilation_context context; - public ContextChanger contextChanger; - - internal using_namespace_list using_list = new using_namespace_list(); - internal using_namespace_list interface_using_list = new using_namespace_list(); - - // SSM 6/08/15 Стек для хранения вложенных лямбд для одной цели - вычислить истинный тип выражения, присваиваемого Result. Это нужно для выбора перегруженной функции, у которой параметр лямбда и один из типов возвращаемого значения в точности совпадает с типом возвращаемого значения лямбды - internal Stack stflambda = new Stack(); - - //TODO: Загнать в request. - motivation_keeper motivation_keeper = new motivation_keeper(); - - private PascalABCCompiler.TreeRealization.unit_node_list _referenced_units; - - private common_unit_node _compiled_unit; - - private common_unit_node _system_unit; - internal bool debug=true; - internal bool debugging=false; - internal List ErrorsList; - internal List WarningsList; - internal Dictionary docs; - public bool for_native_code = false; - internal Dictionary DirectivesToNodesLinks; - public bool ThrowCompilationError = true; - public bool MustVisitBody = true; - public LambdaProcessingState lambdaProcessingState = LambdaProcessingState.None; //lroman - - #region (MikhailoMMX) Положение визитора относительно параллельных конструкций - public ParallelPosition CurrentParallelPosition = ParallelPosition.Outside; - #endregion - - private int num = 0; - - public string UniqueNumStr() - { - num++; - return num.ToString(); - } - - internal Errors.Error LastError() - { - Errors.Error err = ErrorsList[ErrorsList.Count-1]; - ErrorsList.RemoveAt(ErrorsList.Count - 1); - return err; - } - - internal void RemoveLastError() - { - if (ErrorsList.Count > 0) - ErrorsList.RemoveAt(ErrorsList.Count - 1); - } - - internal void AddError(Errors.Error err, bool shouldReturn=false) - { - if (ThrowCompilationError || !shouldReturn /*|| err.MustThrow && !shouldReturn*/) - { - throw err; - } - else - { - ErrorsList.Add(err); - } - } - - internal void AddError(location loc, string ErrResourceString, params object[] values) - { - Errors.Error err = new SimpleSemanticError(loc, ErrResourceString, values); - if (ThrowCompilationError) - { - throw err; - } - else - { - ErrorsList.Add(err); - } - } - - internal void AddWarning(Errors.CompilerWarning err) - { - WarningsList.Add(err); - } - - private bool _record_created = false; - - private bool with_class_name=false; - - internal bool from_pabc_dll = false; - - private bool type_section_converting = false; - - private Dictionary set_intls = new Dictionary(); - - //(ssyy) Дополнительные ограничения на параметры generic-типа. - //Например, возможность объявить указатель на этот тип-параметр. - internal Dictionary generic_param_abilities = - new Dictionary(); - - private GenericParameterAbilities get_type_abilities(type_node t) - { - GenericParameterAbilities gpa; - if (generic_param_abilities.TryGetValue(t, out gpa)) return gpa; - gpa = new GenericParameterAbilities(); - generic_param_abilities.Add(t, gpa); - return gpa; - } - - private void internal_reset() - { - PascalABCCompiler.SystemLibrary.SystemLibInitializer.initialization_properties init_properties = - new PascalABCCompiler.SystemLibrary.SystemLibInitializer.initialization_properties(); - - init_properties.break_executor = make_break_node; - init_properties.continue_executor = make_continue_node; - init_properties.exit_executor = make_exit_node; - - _system_unit = SystemLibrary.SystemLibInitializer.make_system_unit(convertion_data_and_alghoritms.symbol_table, - init_properties); - SystemLibrary.SystemLibrary.system_unit = _system_unit; - generic_convertions.reset_generics(); - generic_convertions.visitor = this; - _record_created = false; - RefTypesForCheckPointersTypeForDotNetFramework.Clear(); - reset_for_interface(); - _is_interface_part = false; - with_class_name = false; - disable_order_independ = false; - generic_param_abilities.Clear(); - current_converted_method_not_in_class_defined = false; - assign_is_converting = false; - motivation_keeper.reset(); - SystemLibrary.SystemLibInitializer.NeedsToRestore.Clear(); - type_section_converting = false; - ThrowCompilationError = true; - #region MikhailoMMX, реинициализация класса OpenMP - OpenMP.InternalReset(); - CurrentParallelPosition = ParallelPosition.Outside; - #endregion - - lambdaProcessingState = LambdaProcessingState.None; //lroman - CapturedVariablesSubstitutionClassGenerator.Reset(); - } - - public syntax_tree_visitor() - { - convertion_data_and_alghoritms = new convertion_data_and_alghoritms(this); - ret = new returner(this); - context = new compilation_context(convertion_data_and_alghoritms, this); - contextChanger = new ContextChanger(context); - internal_reset(); - } - - - private void release_system_module() - { - SystemUnitAssigned = false; - SystemLibrary.SystemLibInitializer.format_function = null; - SystemLibrary.SystemLibInitializer.read_procedure = null; - SystemLibrary.SystemLibInitializer.write_procedure = null; - SystemLibrary.SystemLibInitializer.writeln_procedure = null; - SystemLibrary.SystemLibInitializer.readln_procedure = null; - SystemLibrary.SystemLibInitializer.TextFileType = null; - SystemLibrary.SystemLibInitializer.TextFileInitProcedure = null; - SystemLibrary.SystemLibInitializer.BinaryFileType = null; - SystemLibrary.SystemLibInitializer.AbstractBinaryFileType = null; - SystemLibrary.SystemLibInitializer.PointerOutputType = null; - SystemLibrary.SystemLibInitializer.BinaryFileInitProcedure = null; - SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure = null; - SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure = null; - SystemLibrary.SystemLibInitializer.TypedFileType = null; - SystemLibrary.SystemLibInitializer.TypedFileInitProcedure = null; - SystemLibrary.SystemLibInitializer.TypedFileReadProcedure = null; - SystemLibrary.SystemLibInitializer.ShortStringType = null; - SystemLibrary.SystemLibInitializer.ShortStringTypeInitProcedure = null; - SystemLibrary.SystemLibInitializer.TypedSetType = null; - SystemLibrary.SystemLibInitializer.SetUnionProcedure = null; - SystemLibrary.SystemLibInitializer.SetIntersectProcedure = null; - SystemLibrary.SystemLibInitializer.SetSubtractProcedure = null; - SystemLibrary.SystemLibInitializer.InSetProcedure = null; - SystemLibrary.SystemLibInitializer.CreateSetProcedure = null; - SystemLibrary.SystemLibInitializer.TypedSetInitProcedure = null; - SystemLibrary.SystemLibInitializer.IncludeProcedure = null; - SystemLibrary.SystemLibInitializer.ExcludeProcedure = null; - SystemLibrary.SystemLibInitializer.DiapasonType = null; - SystemLibrary.SystemLibInitializer.CreateDiapason = null; - SystemLibrary.SystemLibInitializer.CreateObjDiapason = null; - SystemLibrary.SystemLibInitializer.CompareSetEquals = null; - SystemLibrary.SystemLibInitializer.CompareSetInEquals = null; - SystemLibrary.SystemLibInitializer.CompareSetLess = null; - SystemLibrary.SystemLibInitializer.CompareSetLessEqual = null; - SystemLibrary.SystemLibInitializer.CompareSetGreater = null; - SystemLibrary.SystemLibInitializer.CompareSetGreaterEqual = null; - SystemLibrary.SystemLibInitializer.IncProcedure = null; - SystemLibrary.SystemLibInitializer.DecProcedure = null; - SystemLibrary.SystemLibInitializer.SuccFunction = null; - SystemLibrary.SystemLibInitializer.PredFunction = null; - SystemLibrary.SystemLibInitializer.OrdFunction = null; - SystemLibrary.SystemLibInitializer.TypedSetInitProcedureWithBounds = null; - SystemLibrary.SystemLibInitializer.TypedSetInitWithShortString = null; - SystemLibrary.SystemLibInitializer.AssignSetProcedure = null; - SystemLibrary.SystemLibInitializer.AssignSetProcedureWithBounds = null; - SystemLibrary.SystemLibInitializer.ClipProcedure = null; - SystemLibrary.SystemLibInitializer.ClipFunction = null; - SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction = null; - SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure = null; - SystemLibrary.SystemLibInitializer.ClipShortStringProcedure = null; - SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure = null; - SystemLibrary.SystemLibInitializer.SetCharInShortStringProcedure = null; - SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure = null; - SystemLibrary.SystemLibInitializer.SetLengthProcedure = null; - SystemLibrary.SystemLibInitializer.read_short_string_procedure = null; - SystemLibrary.SystemLibInitializer.read_short_string_from_file_procedure = null; - SystemLibrary.SystemLibInitializer.InsertProcedure = null; - SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure = null; - SystemLibrary.SystemLibInitializer.DeleteProcedure = null; - SystemLibrary.SystemLibInitializer.LowFunction = null; - SystemLibrary.SystemLibInitializer.HighFunction = null; - SystemLibrary.SystemLibInitializer.CheckCanUsePointerOnTypeProcedure = null; - SystemLibrary.SystemLibInitializer.CheckCanUseTypeForBinaryFilesProcedure = null; - SystemLibrary.SystemLibInitializer.CheckCanUseTypeForTypedFilesProcedure = null; - SystemLibrary.SystemLibInitializer.RuntimeDetermineTypeFunction = null; - SystemLibrary.SystemLibInitializer.RuntimeInitializeFunction = null; - SystemLibrary.SystemLibInitializer.PointerToStringFunction = null; - SystemLibrary.SystemLibInitializer.GetRuntimeSizeFunction = null; - SystemLibrary.SystemLibInitializer.PointerOutputConstructor = null; - SystemLibrary.SystemLibInitializer.StrProcedure = null; - SystemLibrary.SystemLibInitializer.ChrUnicodeFunction = null; - SystemLibrary.SystemLibInitializer.AssertProcedure = null; - SystemLibrary.SystemLibInitializer.CheckRangeFunction = null; - SystemLibrary.SystemLibInitializer.CheckCharRangeFunction = null; - SystemLibrary.SystemLibInitializer.CopyWithSizeFunction = null; - SystemLibrary.SystemLibInitializer.ArrayCopyFunction = null; - SystemLibrary.SystemLibInitializer.ObjectType = null; - SystemLibrary.SystemLibInitializer.StringType = null; - SystemLibrary.SystemLibInitializer.ConfigVariable = null; - SystemLibrary.SystemLibInitializer.PascalABCVersion = null; - } - - internal bool SystemUnitAssigned = false; - - public static void init_system_module(common_unit_node psystem_unit) - { - SystemLibrary.SystemLibInitializer.format_function = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.format_procedure_name); - SystemLibrary.SystemLibInitializer.read_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.read_procedure_name); - SystemLibrary.SystemLibInitializer.write_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.write_procedure_name); - SystemLibrary.SystemLibInitializer.writeln_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.writeln_procedure_name); - SystemLibrary.SystemLibInitializer.readln_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.readln_procedure_name); - SystemLibrary.SystemLibInitializer.TextFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.text_file_name_type_name); - SystemLibrary.SystemLibInitializer.TextFileInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TextFileInitProcedureName); - SystemLibrary.SystemLibInitializer.BinaryFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.BinaryFileTypeName); - SystemLibrary.SystemLibInitializer.AbstractBinaryFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AbstractBinaryFileTypeName); - SystemLibrary.SystemLibInitializer.PointerOutputType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PointerOutputTypeName); - SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.BinaryFileReadProcedureName); - SystemLibrary.SystemLibInitializer.BinaryFileInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.BinaryFileInitProcedureName); - SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.StringDefaultPropertySetProcedureName); - SystemLibrary.SystemLibInitializer.TypedFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedFileTypeName); - SystemLibrary.SystemLibInitializer.TypedFileInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedFileInitProcedureName); - SystemLibrary.SystemLibInitializer.TypedFileReadProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedFileReadProcedureName); - SystemLibrary.SystemLibInitializer.ClipShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipShortString); - SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.GetCharInShortString); - SystemLibrary.SystemLibInitializer.SetCharInShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.SetCharInShortString); - //SystemLibrary.SystemLibInitializer.ShortStringType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ShortStringTypeName); - //SystemLibrary.SystemLibInitializer.ShortStringTypeInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ShortStringTypeInitProcedure); - SystemLibrary.SystemLibInitializer.TypedSetType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.set_name); - SystemLibrary.SystemLibInitializer.TypedSetInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedSetInitProcedure); - SystemLibrary.SystemLibInitializer.SetUnionProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.union_of_set); - SystemLibrary.SystemLibInitializer.SetIntersectProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.intersect_of_set); - SystemLibrary.SystemLibInitializer.SetSubtractProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.subtract_of_set); - SystemLibrary.SystemLibInitializer.InSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.in_set); - SystemLibrary.SystemLibInitializer.CreateSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CreateSetProcedure); - SystemLibrary.SystemLibInitializer.IncludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.IncludeProcedure); - SystemLibrary.SystemLibInitializer.ExcludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ExcludeProcedure); - SystemLibrary.SystemLibInitializer.DiapasonType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.DiapasonType); - SystemLibrary.SystemLibInitializer.CreateDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CreateDiapason); - SystemLibrary.SystemLibInitializer.CreateObjDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CreateObjDiapason); - SystemLibrary.SystemLibInitializer.CompareSetEquals = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetEquals); - SystemLibrary.SystemLibInitializer.CompareSetInEquals = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetInEquals); - SystemLibrary.SystemLibInitializer.CompareSetLess = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetLess); - SystemLibrary.SystemLibInitializer.CompareSetLessEqual = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetLessEqual); - SystemLibrary.SystemLibInitializer.CompareSetGreater = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetGreater); - SystemLibrary.SystemLibInitializer.CompareSetGreaterEqual = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetGreaterEqual); - SystemLibrary.SystemLibInitializer.IncProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.IncProcedure); - SystemLibrary.SystemLibInitializer.DecProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.DecProcedure); - SystemLibrary.SystemLibInitializer.SuccFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.SuccFunction); - SystemLibrary.SystemLibInitializer.PredFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PredFunction); - SystemLibrary.SystemLibInitializer.OrdFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.OrdFunction); - SystemLibrary.SystemLibInitializer.TypedSetInitProcedureWithBounds = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedSetInitProcedureWithBounds); - SystemLibrary.SystemLibInitializer.TypedSetInitWithShortString = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedSetInitWithShortString); - SystemLibrary.SystemLibInitializer.AssignSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AssignSetProcedure); - SystemLibrary.SystemLibInitializer.AssignSetProcedureWithBounds = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AssignSetProcedureWithBounds); - SystemLibrary.SystemLibInitializer.ClipProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipProcedure); - SystemLibrary.SystemLibInitializer.ClipFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipFunction); - SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipShortStringInSetFunction); - SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipShortStringInSetProcedure); - SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.set_length_for_short_string); - SystemLibrary.SystemLibInitializer.SetLengthProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.set_length_procedure_name); - SystemLibrary.SystemLibInitializer.read_short_string_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.read_short_string); - SystemLibrary.SystemLibInitializer.read_short_string_from_file_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.read_short_string_from_file); - SystemLibrary.SystemLibInitializer.InsertProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit,compiler_string_consts.Insert); - SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit,compiler_string_consts.InsertInShortString); - SystemLibrary.SystemLibInitializer.DeleteProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit,compiler_string_consts.Delete); - SystemLibrary.SystemLibInitializer.LowFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit,compiler_string_consts.Low); - SystemLibrary.SystemLibInitializer.HighFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit,compiler_string_consts.High); - SystemLibrary.SystemLibInitializer.CheckCanUsePointerOnTypeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CheckCanUsePointerOnType_proc_name); - SystemLibrary.SystemLibInitializer.CheckCanUseTypeForBinaryFilesProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CheckCanUseTypeForBinaryFiles_proc_name); - SystemLibrary.SystemLibInitializer.CheckCanUseTypeForTypedFilesProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CheckCanUseTypeForTypedFiles_proc_name); - SystemLibrary.SystemLibInitializer.RuntimeDetermineTypeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.RuntimeDetermineType_func_name); - SystemLibrary.SystemLibInitializer.RuntimeInitializeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.RuntimeInitializeFunction_func_name); - SystemLibrary.SystemLibInitializer.PointerToStringFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PointerToStringFunction_func_name); - SystemLibrary.SystemLibInitializer.GetRuntimeSizeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.GetRuntimeSizeFunction_func_name); - SystemLibrary.SystemLibInitializer.StrProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.StrProcedure_func_name); - SystemLibrary.SystemLibInitializer.PascalABCVersion = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PascalABCVersion_func_name); - SystemLibrary.SystemLibInitializer.ChrUnicodeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ChrUnicodeFunction_func_name); - SystemLibrary.SystemLibInitializer.AssertProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AssertProcedure); - SystemLibrary.SystemLibInitializer.CheckRangeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.check_in_range); - SystemLibrary.SystemLibInitializer.CheckCharRangeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.check_in_range_char); - SystemLibrary.SystemLibInitializer.CopyWithSizeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CopyWithSizeFunction); - SystemLibrary.SystemLibInitializer.ArrayCopyFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ArrayCopyFunction); - SystemLibrary.SystemLibInitializer.ConfigVariable = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.config_variable_name); - //SystemLibrary.SystemLibrary.make_type_conversion(SystemLibrary.SystemLibInitializer.ShortStringType.sym_info as type_node,SystemLibrary.SystemLibrary.string_type,type_compare.less_type,SemanticTree.basic_function_type.none,true); - //SystemLibrary.SystemLibrary.make_type_conversion(SystemLibrary.SystemLibrary.string_type,SystemLibrary.SystemLibInitializer.ShortStringType.sym_info as type_node,type_compare.greater_type,SemanticTree.basic_function_type.none,true); - if (SystemLibrary.SystemLibInitializer.TextFileType.Found) - SystemLibrary.SystemLibInitializer.TextFileType.TypeNode.type_special_kind = PascalABCCompiler.SemanticTree.type_special_kind.text_file; - if (SemanticRules.GenerateNativeCode) - { - SystemLibrary.SystemLibInitializer.ObjectType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ObjectType); - if (SystemLibrary.SystemLibInitializer.ObjectType.Found) - SemanticRules.ClassBaseType = SystemLibrary.SystemLibInitializer.ObjectType.sym_info as TreeRealization.type_node; - SystemLibrary.SystemLibInitializer.StringType = new PascalABCCompiler.SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.StringType); - if (SystemLibrary.SystemLibInitializer.StringType.Found) - SemanticRules.StringType = SystemLibrary.SystemLibInitializer.StringType.sym_info as TreeRealization.type_node; - } - } - - public static void init_system_module_from_dll(dot_net_unit_node psystem_unit) - { - SystemLibrary.SystemLibInitializer.format_function = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.format_procedure_name); - SystemLibrary.SystemLibInitializer.read_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.read_procedure_name); - SystemLibrary.SystemLibInitializer.write_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.write_procedure_name); - SystemLibrary.SystemLibInitializer.writeln_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.writeln_procedure_name); - SystemLibrary.SystemLibInitializer.readln_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.readln_procedure_name); - SystemLibrary.SystemLibInitializer.TextFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.text_file_name_type_name); - SystemLibrary.SystemLibInitializer.TextFileInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TextFileInitProcedureName); - SystemLibrary.SystemLibInitializer.BinaryFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.BinaryFileTypeName); - SystemLibrary.SystemLibInitializer.AbstractBinaryFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AbstractBinaryFileTypeName); - SystemLibrary.SystemLibInitializer.PointerOutputType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PointerOutputTypeName); - SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.BinaryFileReadProcedureName); - SystemLibrary.SystemLibInitializer.BinaryFileInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.BinaryFileInitProcedureName); - SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.StringDefaultPropertySetProcedureName); - SystemLibrary.SystemLibInitializer.TypedFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedFileTypeName); - SystemLibrary.SystemLibInitializer.TypedFileInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedFileInitProcedureName); - SystemLibrary.SystemLibInitializer.TypedFileReadProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedFileReadProcedureName); - SystemLibrary.SystemLibInitializer.ClipShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipShortString); - SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.GetCharInShortString); - SystemLibrary.SystemLibInitializer.SetCharInShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.SetCharInShortString); - //SystemLibrary.SystemLibInitializer.ShortStringType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ShortStringTypeName); - //SystemLibrary.SystemLibInitializer.ShortStringTypeInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ShortStringTypeInitProcedure); - SystemLibrary.SystemLibInitializer.TypedSetType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.set_name); - SystemLibrary.SystemLibInitializer.TypedSetInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedSetInitProcedure); - SystemLibrary.SystemLibInitializer.SetUnionProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.union_of_set); - SystemLibrary.SystemLibInitializer.SetIntersectProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.intersect_of_set); - SystemLibrary.SystemLibInitializer.SetSubtractProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.subtract_of_set); - SystemLibrary.SystemLibInitializer.InSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.in_set); - SystemLibrary.SystemLibInitializer.CreateSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CreateSetProcedure); - SystemLibrary.SystemLibInitializer.IncludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.IncludeProcedure); - SystemLibrary.SystemLibInitializer.ExcludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ExcludeProcedure); - SystemLibrary.SystemLibInitializer.DiapasonType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.DiapasonType); - SystemLibrary.SystemLibInitializer.CreateDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CreateDiapason); - SystemLibrary.SystemLibInitializer.CreateObjDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CreateObjDiapason); - SystemLibrary.SystemLibInitializer.CompareSetEquals = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetEquals); - SystemLibrary.SystemLibInitializer.CompareSetInEquals = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetInEquals); - SystemLibrary.SystemLibInitializer.CompareSetLess = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetLess); - SystemLibrary.SystemLibInitializer.CompareSetLessEqual = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetLessEqual); - SystemLibrary.SystemLibInitializer.CompareSetGreater = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetGreater); - SystemLibrary.SystemLibInitializer.CompareSetGreaterEqual = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetGreaterEqual); - SystemLibrary.SystemLibInitializer.IncProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.IncProcedure); - SystemLibrary.SystemLibInitializer.DecProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.DecProcedure); - SystemLibrary.SystemLibInitializer.SuccFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.SuccFunction); - SystemLibrary.SystemLibInitializer.PredFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PredFunction); - SystemLibrary.SystemLibInitializer.OrdFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.OrdFunction); - SystemLibrary.SystemLibInitializer.TypedSetInitProcedureWithBounds = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedSetInitProcedureWithBounds); - SystemLibrary.SystemLibInitializer.TypedSetInitWithShortString = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedSetInitWithShortString); - SystemLibrary.SystemLibInitializer.AssignSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AssignSetProcedure); - SystemLibrary.SystemLibInitializer.AssignSetProcedureWithBounds = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AssignSetProcedureWithBounds); - SystemLibrary.SystemLibInitializer.ClipProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipProcedure); - SystemLibrary.SystemLibInitializer.ClipFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipFunction); - SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipShortStringInSetFunction); - SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipShortStringInSetProcedure); - SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.set_length_for_short_string); - SystemLibrary.SystemLibInitializer.SetLengthProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.set_length_procedure_name); - SystemLibrary.SystemLibInitializer.read_short_string_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.read_short_string); - SystemLibrary.SystemLibInitializer.read_short_string_from_file_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.read_short_string_from_file); - SystemLibrary.SystemLibInitializer.InsertProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.Insert); - SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.InsertInShortString); - SystemLibrary.SystemLibInitializer.DeleteProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.Delete); - SystemLibrary.SystemLibInitializer.LowFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.Low); - SystemLibrary.SystemLibInitializer.HighFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.High); - SystemLibrary.SystemLibInitializer.CheckCanUsePointerOnTypeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CheckCanUsePointerOnType_proc_name); - SystemLibrary.SystemLibInitializer.CheckCanUseTypeForBinaryFilesProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CheckCanUseTypeForBinaryFiles_proc_name); - SystemLibrary.SystemLibInitializer.CheckCanUseTypeForTypedFilesProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CheckCanUseTypeForTypedFiles_proc_name); - SystemLibrary.SystemLibInitializer.RuntimeDetermineTypeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.RuntimeDetermineType_func_name); - SystemLibrary.SystemLibInitializer.RuntimeInitializeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.RuntimeInitializeFunction_func_name); - SystemLibrary.SystemLibInitializer.PointerToStringFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PointerToStringFunction_func_name); - SystemLibrary.SystemLibInitializer.GetRuntimeSizeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.GetRuntimeSizeFunction_func_name); - SystemLibrary.SystemLibInitializer.StrProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.StrProcedure_func_name); - SystemLibrary.SystemLibInitializer.PascalABCVersion = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PascalABCVersion_func_name); - SystemLibrary.SystemLibInitializer.ChrUnicodeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ChrUnicodeFunction_func_name); - SystemLibrary.SystemLibInitializer.AssertProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AssertProcedure); - SystemLibrary.SystemLibInitializer.CheckRangeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.check_in_range); - SystemLibrary.SystemLibInitializer.CheckCharRangeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.check_in_range_char); - SystemLibrary.SystemLibInitializer.CopyWithSizeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CopyWithSizeFunction); - SystemLibrary.SystemLibInitializer.ArrayCopyFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ArrayCopyFunction); - SystemLibrary.SystemLibInitializer.ConfigVariable = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.config_variable_name); - //AddSpecialOperatorsToSetType(); - //SystemLibrary.SystemLibrary.make_type_conversion(SystemLibrary.SystemLibInitializer.ShortStringType.sym_info as type_node,SystemLibrary.SystemLibrary.string_type,type_compare.less_type,SemanticTree.basic_function_type.none,true); - //SystemLibrary.SystemLibrary.make_type_conversion(SystemLibrary.SystemLibrary.string_type,SystemLibrary.SystemLibInitializer.ShortStringType.sym_info as type_node,type_compare.greater_type,SemanticTree.basic_function_type.none,true); - if (SystemLibrary.SystemLibInitializer.TextFileType.Found) - SystemLibrary.SystemLibInitializer.TextFileType.TypeNode.type_special_kind = PascalABCCompiler.SemanticTree.type_special_kind.text_file; - } - - private void get_system_module(common_unit_node psystem_unit) - { - init_system_module(psystem_unit); - //esli zapustili v otladke, to vosstanovim mnozhestvo i procedury sozdanija diapasonov, inache ne budet rabotat - if (debugging) - { - List si = SystemLibrary.SystemLibInitializer.CreateDiapason.SymbolInfo; - si = SystemLibrary.SystemLibInitializer.CreateObjDiapason.SymbolInfo; - si = SystemLibrary.SystemLibInitializer.TypedSetType.SymbolInfo; - } - //if (SystemLibrary.SystemLibInitializer.TextFileType.Found) - // SystemLibrary.SystemLibInitializer.TextFileType.GetTypeNodeSpecials().type_special_kind = PascalABCCompiler.SemanticTree.type_special_kind.text_file; - SystemUnitAssigned = true; - CreateSpecialFields(psystem_unit); - } - - private void get_system_module_from_dll(dot_net_unit_node psystem_unit) - { - init_system_module_from_dll(psystem_unit); - //esli zapustili v otladke, to vosstanovim mnozhestvo i procedury sozdanija diapasonov, inache ne budet rabotat - if (debugging) - { - List si = SystemLibrary.SystemLibInitializer.CreateDiapason.SymbolInfo; - si = SystemLibrary.SystemLibInitializer.CreateObjDiapason.SymbolInfo; - si = SystemLibrary.SystemLibInitializer.TypedSetType.SymbolInfo; - } - //if (SystemLibrary.SystemLibInitializer.TextFileType.Found) - // SystemLibrary.SystemLibInitializer.TextFileType.GetTypeNodeSpecials().type_special_kind = PascalABCCompiler.SemanticTree.type_special_kind.text_file; - SystemUnitAssigned = true; - //CreateSpecialFields(psystem_unit); - } - - private void AddSpecialOperatorsToSetType() - { - if (SystemLibrary.SystemLibInitializer.TypedSetType.NotFound) - return; - common_type_node tctn = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as common_type_node; - tctn.type_special_kind = SemanticTree.type_special_kind.base_set_type; - tctn.scope.AddSymbol(compiler_string_consts.plus_name, SystemLibrary.SystemLibInitializer.SetUnionProcedure.SymbolInfo.FirstOrDefault()); - tctn.scope.AddSymbol(compiler_string_consts.mul_name, SystemLibrary.SystemLibInitializer.SetIntersectProcedure.SymbolInfo.FirstOrDefault()); - tctn.scope.AddSymbol(compiler_string_consts.in_name, SystemLibrary.SystemLibInitializer.InSetProcedure.SymbolInfo.FirstOrDefault()); - tctn.scope.AddSymbol(compiler_string_consts.minus_name, SystemLibrary.SystemLibInitializer.SetSubtractProcedure.SymbolInfo.FirstOrDefault()); - tctn.scope.AddSymbol(compiler_string_consts.gr_name, SystemLibrary.SystemLibInitializer.CompareSetGreater.SymbolInfo.FirstOrDefault()); - tctn.scope.AddSymbol(compiler_string_consts.greq_name, SystemLibrary.SystemLibInitializer.CompareSetGreaterEqual.SymbolInfo.FirstOrDefault()); - tctn.scope.AddSymbol(compiler_string_consts.sm_name, SystemLibrary.SystemLibInitializer.CompareSetLess.SymbolInfo.FirstOrDefault()); - tctn.scope.AddSymbol(compiler_string_consts.smeq_name, SystemLibrary.SystemLibInitializer.CompareSetLessEqual.SymbolInfo.FirstOrDefault()); - tctn.scope.AddSymbol(compiler_string_consts.eq_name, SystemLibrary.SystemLibInitializer.CompareSetEquals.SymbolInfo.FirstOrDefault()); - tctn.scope.AddSymbol(compiler_string_consts.noteq_name, SystemLibrary.SystemLibInitializer.CompareSetInEquals.SymbolInfo.FirstOrDefault()); - } - - private void CreateSpecialFields(common_unit_node psystem_unit) - { - List sil = psystem_unit.scope.Find(compiler_string_consts.IsConsoleApplicationVariableName); - if (sil != null && sil.FirstOrDefault().sym_info is namespace_variable) - { - namespace_variable_reference nvr = new namespace_variable_reference(sil.FirstOrDefault().sym_info as namespace_variable, null); - psystem_unit.IsConsoleApplicationVariableAssignExpr = make_assign_operator(nvr, psystem_unit.IsConsoleApplicationVariableValue, null); - } - } - - private void UpdateUnitDefinitionItemForUnit(common_unit_node unit) - { - if (!from_pabc_dll) - { - SystemLibrary.SystemLibInitializer.read_procedure = new SystemLibrary.UnitDefinitionItem(unit, compiler_string_consts.read_procedure_name); - SystemLibrary.SystemLibInitializer.readln_procedure = new SystemLibrary.UnitDefinitionItem(unit, compiler_string_consts.readln_procedure_name); - } - else - { - //SystemLibrary.SystemLibInitializer.read_procedure = new SystemLibrary.UnitDefinitionItem(unit, compiler_string_consts.read_procedure_name); - //SystemLibrary.SystemLibInitializer.readln_procedure = new SystemLibrary.UnitDefinitionItem(unit, compiler_string_consts.readln_procedure_name); - } - } - - public void reset() - { - _system_unit = null; - SystemLibrary.SystemLibrary.system_unit = null; - //SystemLibrary.SystemLibrary.Reset(); - SystemUnitAssigned = false; - _compiled_unit = null; - _referenced_units = null; - current_document = null; - using_list.clear(); - //_referenced_units.clear(); - ret.reset(); - motivation_keeper.reset(); - context.reset(); - convertion_data_and_alghoritms.reset(); - //compiled_type_node.compiled_types.Clear(); - internal_reset(); - release_system_module(); - WaitedRefTypes.Clear(); - set_intls.Clear(); - NetHelper.NetHelper.reset(); - if (ErrorsList != null) - ErrorsList.Clear(); - from_pabc_dll = false; - in_interface_part = false; - compiled_type_node[] ctns = new compiled_type_node[compiled_type_node.compiled_types.Values.Count]; - compiled_type_node.compiled_types.Values.CopyTo(ctns, 0); - null_type_node.reset(); - foreach (compiled_type_node ctn in ctns) - { - ctn.reinit_scope(); - ctn.clear_generated_names(); - ctn.clear_generated_intersections(); - } - } - - public PascalABCCompiler.Errors.SyntaxError parser_error - { - get - { - return convertion_data_and_alghoritms.parser_error; - } - set - { - convertion_data_and_alghoritms.parser_error = value; - } - } - public System.Collections.Hashtable bad_nodes_in_syntax_tree - { - get - { - return convertion_data_and_alghoritms.bad_nodes_in_syntax_tree; - } - set - { - convertion_data_and_alghoritms.bad_nodes_in_syntax_tree = value; - } - - } - - public PascalABCCompiler.TreeRealization.document CurrentDocument - { - get - { - return current_document; - } - } - - public SymbolTable.TreeConverterSymbolTable SymbolTable - { - get - { - return convertion_data_and_alghoritms.symbol_table; - } - } - - public location get_location(SyntaxTree.syntax_tree_node tn) - { - var tnn = tn; - /*while (tnn.source_context == null && tnn.Parent != null) - { - tnn = tnn.Parent; - }*/ - var tns = tnn.source_context; - - if (tns == null) - { - return null; - } - document d = current_document; - if (tns.FileName != null && (d == null || d.file_name != tns.FileName)) - d = new document(tns.FileName); - return new location(tns.begin_position.line_num, tns.begin_position.column_num, - tns.end_position.line_num, tns.end_position.column_num, d); - } - public location get_right_location(SyntaxTree.syntax_tree_node tn) - { - if (tn.source_context == null) - { - return null; - } - return new location(tn.source_context.end_position.line_num, tn.source_context.end_position.column_num, - tn.source_context.end_position.line_num, tn.source_context.end_position.column_num, current_document); - } - - public location get_location_with_check(SyntaxTree.syntax_tree_node tn) - { - if (tn == null || tn.source_context == null) - { - return null; - } - document d = current_document; - if (tn.source_context.FileName != null) - d = new document(tn.source_context.FileName); - return new location(tn.source_context.begin_position.line_num, tn.source_context.begin_position.column_num, - tn.source_context.end_position.line_num, tn.source_context.end_position.column_num, d); - } - - public common_unit_node compiled_unit - { - get - { - return _compiled_unit; - } - //TODO: Нужен ли set? - set - { - _compiled_unit = value; - } - } - - public PascalABCCompiler.TreeRealization.unit_node_list referenced_units - { - get - { - return _referenced_units; - } - set - { - _referenced_units = value; - } - } - - //TODO: Может вынести всю работу с returner-ами в convertion_data_and_alghoritms? - //Методы returner-а. - //Запрос на построение и получение конвертированного поддерева. - //Нежесткая проверка существования узла. - private statement_node convert_weak(SyntaxTree.statement st) - { - if (st == null) - { - return null; - } - - convertion_data_and_alghoritms.check_node_parser_error(st); - - //st = prepare_statement(st); - - statement_node sn = ret.visit(st); - //sn.loc=get_location(st); - return sn; - } - - private expression_node convert_weak(SyntaxTree.expression expr) - { - if (expr == null) - { - return null; - } - - convertion_data_and_alghoritms.check_node_parser_error(expr); - - //Посмотреть, может вызвать ошибку - //ssyy - motivation_keeper.reset(); - //\ssyy - - expression_node en = ret.visit(expr); - //en.loc=get_location(expr); - return en; - } - - private type_node convert_weak(SyntaxTree.type_definition type_def) - { - if (type_def == null) - { - return null; - } - - convertion_data_and_alghoritms.check_node_parser_error(type_def); - - return ret.visit(type_def); - } - - //Жесткая проверка существования узла. Проверка будет осуществлятся только в DEBUG версии. - //Будем верить, что в RELEAS-е все будет работать правильно. - private semantic_node convert_semantic_strong(SyntaxTree.syntax_tree_node tn) - { -#if (DEBUG) - if (tn == null) - { - throw new CompilerInternalError("This syntax tree node can not be null."); - } -#endif - - convertion_data_and_alghoritms.check_node_parser_error(tn); - motivation_keeper.set_motivation_to_expect_semantic_node(); - return ret.visit(tn); - } - - internal statement_node convert_strong(SyntaxTree.statement st) - { -#if (DEBUG) - if (st == null) - { - throw new CompilerInternalError("This syntax tree node can not be null."); - } -#endif - - #region MikhailoMMX, обработка критических секций OpenMP - bool isCritical = false; - SyntaxTree.statement st_orig = st; - if (OpenMP.LocksFound) - if (DirectivesToNodesLinks.ContainsKey(st) && OpenMP.IsCriticalDirective(DirectivesToNodesLinks[st])) - { - //если перед узлом есть директива omp critical - isCritical = true; - OpenMP.TryConvertCritical(ref st, this, DirectivesToNodesLinks[st]); - OpenMP.DisableDirective(st_orig, DirectivesToNodesLinks); - } - #endregion - - convertion_data_and_alghoritms.check_node_parser_error(st); - - //st = prepare_statement(st); - statement_node sn = null; - //try - { - sn = ret.visit(st); - // SSM 19/01/17 закомментировал две следующие строчки - //if (sn == null) - // sn = new empty_statement(null); - } - /*catch (PascalABCCompiler.Errors.Error e) - { - if (ThrowCompilationError) - throw e; - else - { - ErrorsList.Add(e); - return new empty_statement(null); - } - } - catch (Exception e) - { - if (ThrowCompilationError) - throw e; - else - return new empty_statement(null); - }*/ - //sn.loc=get_location(st); - - #region MikhailoMMX, обработка критических секций OpenMP - if (isCritical) - OpenMP.EnableDirective(st_orig, DirectivesToNodesLinks); - #endregion - - return sn; - } - - internal expression_node convert_strong(SyntaxTree.expression expr) - { -#if DEBUG - //var s = expr + "\n"; - //System.IO.File.AppendAllText("d:\\bb17.txt", s); -#endif - -#if (DEBUG) - if (expr == null) - { - throw new CompilerInternalError("This syntax tree node can not be null."); - } -#endif - //if (expr.semantic_ex != null) // SSM 3.1.17 - возвращаем кешированное значение - // return expr.semantic_ex as expression_node; - - convertion_data_and_alghoritms.check_node_parser_error(expr); - - //Посмотреть, может вызвать ошибку - //ssyy - motivation_keeper.reset(); // Это можно закомментировать - все тесты проходят SSM 2/1/17 - //\ssyy - expression_node en = ret.visit(expr); - - //if (lambdaProcessingState == LambdaProcessingState.FinishPhase) - // expr.semantic_ex = en; // SSM 3.1.17 кешируем для последующего обращения - - if (en == null) - AddError(get_location(expr), "EXPRESSION_EXPECTED"); - //en.loc=get_location(expr); - - return en; - } - - internal type_node convert_strong(SyntaxTree.type_definition type_def) - { -#if (DEBUG) - if (type_def == null) - { - throw new CompilerInternalError("This syntax tree node can not be null."); - } -#endif - - convertion_data_and_alghoritms.check_node_parser_error(type_def); - - type_node tn; - SyntaxTree.function_header fh = (type_def as SyntaxTree.function_header); - if (fh != null) - { - tn = convert_function_type(fh, get_location(type_def), context.get_delegate_type_name(), null); - return tn; - } - else - { - SyntaxTree.procedure_header ph = (type_def as SyntaxTree.procedure_header); - if (ph != null) - { - tn = convert_function_type(ph, get_location(type_def), context.get_delegate_type_name(), null); - return tn; - } - } - if (is_direct_type_decl && !(type_def is SyntaxTree.ref_type)) is_direct_type_decl = false; - return ret.visit(type_def); - } - - public addressed_expression convert_address_strong(SyntaxTree.addressed_value av) - { -#if (DEBUG) - if (av == null) - { - throw new CompilerInternalError("This syntax tree node can not be null."); - } -#endif - - convertion_data_and_alghoritms.check_node_parser_error(av); - - motivation_keeper.set_motivation_to_expect_address(); - addressed_expression ae = ret.visit(av); - //ae.loc=get_location(av); - return ae; - } - - //Возвращение конвертированного поддерева. - private void return_value(statement_node stat) - { - ret.return_value(stat); - } - - private void return_value(expression_node expr) - { - ret.return_value(expr); - } - - private void return_value(type_node tn) - { - ret.return_value(tn); - } - - private void return_addressed_value(addressed_expression ae) - { - ret.return_value(ae); - } - - private void return_semantic_value(semantic_node se) - { - ret.return_value(se); - } - - public void weak_node_test_and_visit(SyntaxTree.syntax_tree_node tn) - { - if (tn != null) - { - convertion_data_and_alghoritms.check_node_parser_error(tn); - tn.visit(this); - } - } - - public void hard_node_test_and_visit(SyntaxTree.syntax_tree_node tn) - { -#if (DEBUG) -// try -// { - if (tn == null) - { - throw new CompilerInternalError("This node can not be null"); - } -#endif - convertion_data_and_alghoritms.check_node_parser_error(tn); - if (is_direct_type_decl && !(tn is SyntaxTree.ref_type)) - is_direct_type_decl = false; - tn.visit(this); -/*#if (DEBUG) - } - catch (Exception e) - { - if (tn != null) - throw new Exception("" + tn.source_context.ToString() + System.Environment.NewLine + e.ToString()); - else throw e; - } -#endif*/ - } - - private void assign_doc_info(definition_node dn, SyntaxTree.syntax_tree_node stn) - { - string s = null; - if (docs != null && docs.TryGetValue(stn, out s) && !string.IsNullOrEmpty(s)) - { - dn.documentation = s; - } - return; - } - - //Последний параметер - выходной. Он слдержит список параметров с преобразованиями типов. - private function_node find_function(string name, location loc, PascalABCCompiler.TreeRealization.expressions_list parameters) - { - List sil = context.find(name); - if (sil == null) - { - AddError(new NoFunctionWithThisName(loc)); - } - if (sil.FirstOrDefault().sym_info.general_node_type != general_node_type.function_node) - { - AddError(new ThisIsNotFunctionName(loc)); - } - function_node fn = convertion_data_and_alghoritms.select_function(parameters, sil, loc); - return fn; - } - - //TODO: Обратить внимание на эту функцию. Ее вызовы не приводят к созданиям узлов преобразования типов. - private function_node find_function(string name, location loc, params expression_node[] exprs) - { - expressions_list exprs_list = new expressions_list(); - exprs_list.AddRange(exprs); - return find_function(name, loc, exprs_list); - } - - private expression_node find_operator(SyntaxTree.Operators ot, expression_node expr, location loc) - { - string name = name_reflector.get_name(ot); - //#if (DEBUG) - if (name == null) - { - if (ot == PascalABCCompiler.SyntaxTree.Operators.AddressOf) - { - if (expr.is_addressed == false) - { - AddError(expr.location, "CAN_NOT_GET_ADDRESS_FROM_EXPRESSION"); - } - expression_node res = new get_addr_node(expr, loc); - return res; - } - if (ot == PascalABCCompiler.SyntaxTree.Operators.Dereference) - { - } - throw new CompilerInternalError("Invalid operator name"); - } - //#endif - List sil = expr.type.find(name, context.CurrentScope); - if (sil == null || sil.FirstOrDefault().sym_info is wrapped_definition_node) - { - AddError(new OperatorCanNotBeAppliedToThisType(name, expr)); - } - - expressions_list pars = new expressions_list(); - pars.AddElement(expr); - bool tmp = ThrowCompilationError; - ThrowCompilationError = false; - function_node fn; - fn = convertion_data_and_alghoritms.select_function(pars, sil, loc); - ThrowCompilationError = tmp; - if (fn == null) - { - RemoveLastError(); - AddError(new OperatorCanNotBeAppliedToThisType(name, expr)); - } - expr = pars[0]; -#if (DEBUG) - convertion_data_and_alghoritms.check_operator(fn); -#endif - expression_node exp_node = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, expr); - return exp_node; - } - - private expression_node find_operator(SyntaxTree.Operators ot, expression_node left, expression_node right, location loc) - { - string name = name_reflector.get_name(ot); - return find_operator(name, left, right, loc); - } - - bool CheckExpressionType(expression_node expr) - { - if (expr.type == null) - { - AddError(expr.location, "TYPE_NOT_DEFINED"); - return false; - } - return true; - } - - internal bool one_way_operation(string name) - { - if (name == compiler_string_consts.plusassign_name) return true; - if (name == compiler_string_consts.minusassign_name) return true; - if (name == compiler_string_consts.multassign_name) return true; - if (name == compiler_string_consts.assign_name) return true; - if (name == compiler_string_consts.divassign_name) return true; - return false; - } - - public expression_node find_operator(string name, expression_node left, expression_node right, location loc, bool no_search_in_extension_methods = true) - { -#if (DEBUG) - if (name == null) - { - throw new CompilerInternalError("Invalid operator name"); - } -#endif - // Видимо, это сделано для присваивания, т.к. несимметрично. Но странно - f = nil должно возвращать boolean ! - if (right.semantic_node_type == semantic_node_type.null_const_node) - { - if ( !type_table.is_with_nil_allowed(left.type) && !left.type.IsPointer) - AddError(right.location, "NIL_WITH_VALUE_TYPES_NOT_ALLOWED"); - if (right.conversion_type == null) - right = null_const_node.get_const_node_with_type(left.type, (null_const_node)right); - } - - /*if (left.semantic_node_type == semantic_node_type.null_const_node) - { - if (!type_table.is_with_nil_allowed(right.type) && !right.type.IsPointer) - AddError(left.location, "NIL_WITH_VALUE_TYPES_NOT_ALLOWED"); - left = null_const_node.get_const_node_with_type(right.type, (null_const_node)left); - }*/ - - type_node left_type = left.type; - type_node right_type = right.type; - - if (left_type.semantic_node_type == semantic_node_type.delegated_method) - { - delegated_methods dm1 = (delegated_methods)left_type; - if (dm1.empty_param_method != null) - { - if (dm1.empty_param_method.simple_function_node.return_value_type != null) - { - left_type = dm1.empty_param_method.simple_function_node.return_value_type; - } - } - } - - if (right_type.semantic_node_type == semantic_node_type.delegated_method && !left_type.IsDelegate && left_type.semantic_node_type != semantic_node_type.delegated_method) - { - try_convert_typed_expression_to_function_call(ref right); - if (name != compiler_string_consts.plusassign_name && name != compiler_string_consts.minusassign_name) - try_convert_typed_expression_to_function_call(ref left); - - right_type = right.type; - } - if (right_type.semantic_node_type == semantic_node_type.delegated_method && name != compiler_string_consts.plusassign_name && name != compiler_string_consts.minusassign_name) - { - delegated_methods dm2 = (delegated_methods)right_type; - if (dm2.empty_param_method != null) - { - if (dm2.empty_param_method.simple_function_node.return_value_type != null) - { - right_type = dm2.empty_param_method.simple_function_node.return_value_type; - } - } - } - if (name == "+" && right_type == SystemLibrary.SystemLibrary.char_type && left_type != SystemLibrary.SystemLibrary.string_type) - no_search_in_extension_methods = false; - List sil = left_type.find_in_type(name, left_type.Scope, null, no_search_in_extension_methods); - int added_symbols = -1; - List sil2 = null; - if (left_type != right_type && !one_way_operation(name)) - { - //SymbolInfo si2 = right_type.find(name, context.CurrentScope); - if (sil != null) - sil = new List(sil); - if (name == "+" && right_type != SystemLibrary.SystemLibrary.string_type && left_type == SystemLibrary.SystemLibrary.char_type) - no_search_in_extension_methods = false; - sil2 = right_type.find_in_type(name, right_type.Scope, null, no_search_in_extension_methods); - - if ((sil != null) && (sil2 != null)) - { - //Важная проверка. Возможно один и тот же оператор с одними и теми же типами определен в двух разных классах. - //Возможно она занимает много времени, но, наверное, от нее нельзя отказаться. - List funcs = new List(); - foreach(SymbolInfo sic in sil) - { - if (sic.sym_info.general_node_type != general_node_type.function_node) - { - BasePCUReader.RestoreSymbols(sil, name); - } -#if (DEBUG) - if (sic.sym_info.general_node_type != general_node_type.function_node) - { - throw new CompilerInternalError("Expected operator."); - } -#endif - - function_node fn = (function_node)sic.sym_info; - if (convertion_data_and_alghoritms.is_exist_eq_method_in_list(fn, funcs) == null) - { - //break; - funcs.Add(fn); - } - } - //TODO: Разобраться с зацикливанием. - function_node_list fnl = new function_node_list(); - foreach(SymbolInfo sic in sil2) - { - if (sic.sym_info.general_node_type != general_node_type.function_node) - { - BasePCUReader.RestoreSymbols(sil2, name); - } -#if (DEBUG) - if (sic.sym_info.general_node_type != general_node_type.function_node) - { - throw new CompilerInternalError("Expected operator."); - } -#endif - fnl.AddElement(((function_node)(sic.sym_info))); - } - added_symbols = sil.Count() - 1; - foreach (function_node fnode in fnl) - { - function_node eq_func = convertion_data_and_alghoritms.find_eq_method_in_list(fnode, funcs); - if (eq_func != null) - { - //TODO: Проверить правильно ли это будет работать. - if (eq_func != fnode)//zachem eto nuzhno voobshe?? - { - basic_function_node bbfn1 = fnode as basic_function_node; - basic_function_node bbfn2 = eq_func as basic_function_node; - if ((bbfn1 != null) && (bbfn2 != null)) - { - if (bbfn1.basic_function_type != bbfn2.basic_function_type) - { - AddError(new TwoOperatorsCanBeCalled(eq_func, fnode, left, right)); - } - //sic = sic.Next; - continue; - } - else - { - if (left.type.type_special_kind == SemanticTree.type_special_kind.set_type && right.type.type_special_kind == SemanticTree.type_special_kind.set_type - || left.type.type_special_kind == SemanticTree.type_special_kind.set_type && right.type.type_special_kind == SemanticTree.type_special_kind.base_set_type - || left.type.type_special_kind == SemanticTree.type_special_kind.base_set_type && right.type.type_special_kind == SemanticTree.type_special_kind.set_type - || left.type.type_special_kind == SemanticTree.type_special_kind.base_set_type && right.type.type_special_kind == SemanticTree.type_special_kind.base_set_type - || left.type == SystemLibrary.SystemLibrary.string_type && right.type.type_special_kind == SemanticTree.type_special_kind.short_string - || right.type == SystemLibrary.SystemLibrary.string_type && left.type.type_special_kind == SemanticTree.type_special_kind.short_string - || left.type.type_special_kind == SemanticTree.type_special_kind.short_string && right.type.type_special_kind == SemanticTree.type_special_kind.short_string - || left.type.IsDelegate == right.type.IsDelegate) - { - //if (left.type.find_in_type(name) !=null) - } - else - AddError(new TwoOperatorsCanBeCalled(eq_func, fnode, left, right)); - } - } - } - sil.Add(new SymbolInfo(fnode)); - } - } - else - { - if (sil == null && sil2 != null) - { - sil = sil2; - } - } - } - //if (si == null) - { - if (left_type.semantic_node_type == semantic_node_type.delegated_method && right_type.semantic_node_type == semantic_node_type.delegated_method) - { - List saved_sil = sil; - List saved_sil2 = sil2; - if (!(left is typed_expression)) - AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc)); - base_function_call bfc = ((left as typed_expression).type as delegated_methods).proper_methods[0]; - left = convertion_data_and_alghoritms.explicit_convert_type(left, CreateDelegate(bfc.simple_function_node)); - sil = left.type.find_in_type(name); - if (!(right is typed_expression) && right.type is delegated_methods) - bfc = (right.type as delegated_methods).proper_methods[0]; - else - bfc = ((right as typed_expression).type as delegated_methods).proper_methods[0]; - right = convertion_data_and_alghoritms.explicit_convert_type(right, CreateDelegate(bfc.simple_function_node)); - sil2 = right.type.find_in_type(name); - if (saved_sil != null && sil != null) - { - sil.RemoveRange(1, sil.Count() - 1); - sil.AddRange(saved_sil); - } - else - saved_sil = sil; - if (saved_sil2 != null && sil2 != null) - { - sil2.RemoveRange(1, sil2.Count() - 1); - sil2.AddRange(saved_sil2); - } - else - saved_sil2 = sil2; - if (saved_sil == null) - { - if (!no_search_in_extension_methods) - AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc)); - else - return find_operator(name, left, right, loc, false); - } - - } - else if (left_type.semantic_node_type == semantic_node_type.delegated_method) - { - - } - else if (sil != null && left.semantic_node_type == semantic_node_type.delegated_method) - { - List local_sil = sil; - - } - else if (sil == null) - { - if (no_search_in_extension_methods) - return find_operator(name, left, right, loc, false); - else - { - if (right.type is undefined_type) - AddError(right.location, "CAN_NOT_DEDUCE_TYPE_{0}", ""); - else - AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc)); - } - - } - - } - - // После этой точки right_type и left_type не используются! - - expressions_list pars = null; - function_node fnsel = null; - if (sil != null) - { - foreach (SymbolInfo tmp_si in sil) - { - if (tmp_si.sym_info is wrapped_definition_node) - BasePCUReader.RestoreSymbols(sil, name); - } - } - pars = new expressions_list(); - pars.AddElement(left); - pars.AddElement(right); - bool tmp_throw_error = ThrowCompilationError; - ThrowCompilationError = !no_search_in_extension_methods; - - fnsel = convertion_data_and_alghoritms.select_function(pars, sil, loc); - if (!ThrowCompilationError && fnsel == null) - { - RemoveLastError(); - ThrowCompilationError = tmp_throw_error; - return find_operator(name, left, right, loc, false); - } - else - ThrowCompilationError = tmp_throw_error; - //function_node fnsel=convertion_data_and_alghoritms.select_function(pars,si,loc); - CheckSpecialFunctionCall(sil, pars,loc); - //TODO: А это зачем? Можно передать в create_simple_function_call pars. - left = pars[0]; - right = pars[1]; - if (fnsel == null) - { - AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc)); - } - if (added_symbols != -1 && sil != null && added_symbols < sil.Count()) - sil.RemoveRange(added_symbols + 1, sil.Count() - 1 - added_symbols); - - if (SystemUnitAssigned && in_check_range_region() && name == compiler_string_consts.assign_name && is_range_checkable(left.type) && is_range_checkable(right.type)) - { - ordinal_type_interface oti = left.type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; - if (left.type != SystemLibrary.SystemLibrary.char_type && left.type != SystemLibrary.SystemLibrary.uint64_type && !(oti.lower_value is ulong_const_node)) - if(!(oti.lower_value is enum_const_node) && !(oti.lower_value is char_const_node)) - right = convertion_data_and_alghoritms.convert_type(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CheckRangeFunction.sym_info as common_namespace_function_node, null, convertion_data_and_alghoritms.convert_type(right,SystemLibrary.SystemLibrary.int64_type), convertion_data_and_alghoritms.convert_type(oti.lower_value,SystemLibrary.SystemLibrary.int64_type),convertion_data_and_alghoritms.convert_type(oti.upper_value,SystemLibrary.SystemLibrary.int64_type)),right.type); - else if (oti.lower_value is enum_const_node) - { - right = convertion_data_and_alghoritms.explicit_convert_type(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CheckRangeFunction.sym_info as common_namespace_function_node, null, convertion_data_and_alghoritms.explicit_convert_type(right,SystemLibrary.SystemLibrary.int64_type), - convertion_data_and_alghoritms.explicit_convert_type(oti.lower_value,SystemLibrary.SystemLibrary.int64_type),convertion_data_and_alghoritms.explicit_convert_type(oti.upper_value,SystemLibrary.SystemLibrary.int64_type)),right.type); - } - else if (oti.lower_value is char_const_node) - right = convertion_data_and_alghoritms.create_simple_function_call( - SystemLibrary.SystemLibInitializer.CheckCharRangeFunction.sym_info as common_namespace_function_node, - null, right, oti.lower_value,oti.upper_value - ); - } - expression_node exp_node = convertion_data_and_alghoritms.create_simple_function_call(fnsel, loc, left, right); - return exp_node; - } - - internal bool in_check_range_region() - { - return false; - } - - internal bool is_range_checkable(type_node tn) - { - ordinal_type_interface oti = tn.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; - if (oti != null && !tn.IsEnum && tn != SystemLibrary.SystemLibrary.bool_type) - return true; - return false; - } - - private base_function_call_list convert_functions_to_calls(expression_node obj, List fnl, location loc, bool is_static) - { - base_function_call_list ret = new base_function_call_list(); - foreach (function_node fnode in fnl) - { - base_function_call bfc = null; - switch (fnode.semantic_node_type) - { - case semantic_node_type.common_namespace_function_node: - { - common_namespace_function_node cmfn = fnode as common_namespace_function_node; - common_namespace_function_call cnfc = new common_namespace_function_call(cmfn, loc); - if (cmfn.ConnectedToType != null) - cnfc.parameters.AddElement(obj); - if (cmfn.is_generic_function && !cmfn.is_generic_function_instance && cmfn.ConnectedToType != null && cmfn.parameters.Count == 1) - { - expressions_list parameters = new expressions_list(); - parameters.AddElement(obj); - function_node inst = null; - try - { - inst = generic_convertions.DeduceFunction(cmfn, parameters, true, context, loc); - } - catch - { - continue; - } - cnfc = new common_namespace_function_call((common_namespace_function_node)inst, loc); - if (cmfn.ConnectedToType != null) - cnfc.parameters.AddElement(obj); - } - /*if (cmfn.parameters.Count >= 1 && cmfn.parameters[cmfn.parameters.Count - 1].is_params) - { - convertion_data_and_alghoritms.select_function(cnfc.parameters, new SymbolInfo(cmfn), loc); - - }*/ - bfc = cnfc; - break; - } - case semantic_node_type.basic_function_node: - { - //Может здесь стоит и выругаться, но я не буду пока этого делать. - break; - } - case semantic_node_type.common_in_function_function_node: - { - common_in_function_function_node ciffn = fnode as common_in_function_function_node; - int depth = convertion_data_and_alghoritms.symbol_table.GetRelativeScopeDepth(ciffn.scope, - context.top_function.scope); - common_in_function_function_call ciffc = new common_in_function_function_call(ciffn, depth, loc); - bfc = ciffc; - break; - } - case semantic_node_type.common_method_node: - { - common_method_node cmn = fnode as common_method_node; - //Если cmn конструктор - то плохо, но его не должно сюда попасть. - if (cmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - { - if (!is_static) - { - if (obj == null) - obj = GetCurrentObjectReference(cmn.cont_type.Scope, cmn, loc);//new this_node(context.converted_type, loc); - - common_method_call cmc = new common_method_call(cmn, obj, loc); - cmc.virtual_call = !inherited_ident_processing; - bfc = cmc; - } - //ssyy!!! Мне сложно понять предназначение данного кода, но, по-видимому, - //следует его переписать так. - else if (cmn.is_constructor) - { - if (cmn.parameters.Count == 0) - { - if (cmn.cont_type.IsAbstract) - AddError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", cmn.cont_type.name); - ret.clear(); - ret.AddElement(new common_constructor_call(cmn, loc)); - return ret; - } - } - } - else - { - if (is_static) - { - common_static_method_call csmc = new common_static_method_call(cmn, loc); - bfc = csmc; - } - } - break; - } - case semantic_node_type.compiled_function_node: - { - compiled_function_node cfn = fnode as compiled_function_node; - if (cfn.cont_type.Scope == null && cfn is compiled_function_node) - (cfn.cont_type as compiled_type_node).init_scope(); - - if (cfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - //ispravleno ibond - //if (is_static) - { - - if (cfn.is_generic_function && !cfn.is_generic_function_instance && cfn.ConnectedToType != null && cfn.parameters.Count == 1) - { - expressions_list parameters = new expressions_list(); - parameters.AddElement(obj); - function_node inst = null; - try - { - inst = generic_convertions.DeduceFunction(cfn, parameters, true, context, loc); - } - catch - { - continue; - } - if (inst is common_namespace_function_node) - bfc = new common_namespace_function_call((common_namespace_function_node)inst, loc); - else if (inst is compiled_function_node) - bfc = new compiled_static_method_call((compiled_function_node)inst, loc); - else - bfc = new compiled_static_method_call(cfn, loc); - } - else - { - compiled_static_method_call csmc = new compiled_static_method_call(cfn, loc); - bfc = csmc; - - } - if (cfn.ConnectedToType != null) - bfc.parameters.AddElement(obj); - } - } - else - { - if (!is_static) - { - if (obj == null) - obj = GetCurrentObjectReference(cfn.cont_type.Scope, cfn, loc);//new this_node(context.converted_type, loc); - compiled_function_call cfc = new compiled_function_call(cfn, obj, loc); - cfc.virtual_call = !inherited_ident_processing; - bfc = cfc; - } - } - break; - } - case semantic_node_type.compiled_constructor_node: - { - //Этот код мы вроде не должны вызывать, но если он все-же вызовется. - compiled_constructor_node ccn = fnode as compiled_constructor_node; - compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc); - bfc = ccc; - break; - } - default: - { - throw new CompilerInternalError("Undefined method type."); - } - } - if (bfc != null) - { - ret.AddElement(bfc); - } - } - return ret; - } - - private base_function_call_list create_possible_delegates_list(expression_node obj, List sil, location loc, bool is_static) - { - if (sil == null) - { - return new base_function_call_list(); - } - var fnl = new List(); - foreach(SymbolInfo si in sil) - { - function_node fn = si.sym_info as function_node; - if (si.sym_info is compiled_property_node) - { - fn = (si.sym_info as compiled_property_node).get_function; - } - else if (si.sym_info is common_property_node) - { - fn = (si.sym_info as common_property_node).get_function; - } - if (convertion_data_and_alghoritms.find_eq_method_in_list(fn, fnl) == null) - { - if (!(obj != null && fn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && !fn.is_extension_method)) - { - if (fn.is_extension_method) - { - if (obj != null && (fn.parameters[0].type == obj.type || type_table.compare_types(fn.parameters[0].type, obj.type) == type_compare.greater_type)) - fnl.Insert(0,fn); - else - fnl.Add(fn); - } - else - fnl.Add(fn); - } - } - else - { - - } - } - return convert_functions_to_calls(obj, fnl, loc, is_static); - } - - private base_function_call_list create_possible_delegates_list(expression_node obj, function_node func, location loc, bool is_static) - { - var fnl = new List(); - fnl.Add(func); - return convert_functions_to_calls(obj, fnl, loc, is_static); - } - - internal typed_expression make_delegate_wrapper(expression_node obj, List sil, location loc, bool is_static) - { - base_function_call_list fnl = create_possible_delegates_list(obj, sil, loc, is_static); - if (fnl.Count == 0) - { - if (is_static) - { - AddError(loc, "EXPECTED_STATIC_METHOD"); - } - else - { - if (sil != null && sil.Count != 0 && sil.First().sym_info is basic_function_node) - { - basic_function_node bfn = sil.First().sym_info as basic_function_node; - if (bfn.return_value_type != null) - AddError(loc, "USING_{0}_NOT_ALLOWED_IN_THIS_CONTEXT", bfn.name); - else - AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", bfn.name); - } - else - AddError(loc, "EXPECTED_NON_STATIC_METHOD"); - } - } - delegated_methods dm = new delegated_methods(); - dm.proper_methods.AddRange(fnl); - typed_expression te = new typed_expression(dm, loc); - return te; - } - - internal typed_expression make_delegate_wrapper(expression_node obj, function_node func, location loc, bool is_static) - { - base_function_call_list fnl = create_possible_delegates_list(obj, func, loc, is_static); - if (fnl.Count == 0) - { - if (is_static) - { - AddError(loc, "EXPECTED_STATIC_METHOD"); - } - else - { - AddError(loc, "EXPECTED_NON_STATIC_METHOD"); - } - } - delegated_methods dm = new delegated_methods(); - dm.proper_methods.AddRange(fnl); - typed_expression te = new typed_expression(dm, loc); - return te; - } - - private bool check_name_in_current_scope(string name) - { - - SymbolTable.Scope cscope = context.CurrentScope, name_scope = context.find_first(name).scope; - while (cscope is SymbolTable.BlockScope) - { - if (name_scope == cscope) - return true; - cscope = cscope.TopScope; - } - if (cscope is SymbolTable.UnitImplementationScope && name_scope is SymbolTable.UnitInterfaceScope) - return cscope.TopScope == name_scope; - return cscope == name_scope; - } - - void checkPolymorphicState(definition_node dn,location loc) - { - } - - private type_node find_type(string name, location loc) - { - definition_node di = context.check_name_node_type(name, loc, general_node_type.type_node); - type_node tn = (type_node)di; - return tn; - } - - //(ssyy) разбил - private type_node find_type(SyntaxTree.named_type_reference names, location loc) - { - definition_node di; - SyntaxTree.template_type_reference ttr = names as SyntaxTree.template_type_reference; - if (ttr != null) - { - di = ret.visit(names); - type_node tn = di as type_node; - if (tn == null) - { - AddError(loc, "TYPE_REFERENCE_EXPECTED"); - } - return tn; - } - List sil = context.find_definition_node(names, loc); - if (sil == null && attribute_converted) - { - names.names[names.names.Count-1].name += "Attribute"; - sil = context.find_definition_node(names, loc); - } - - if (sil != null && sil.FirstOrDefault().sym_info != null && sil.FirstOrDefault().sym_info.general_node_type == general_node_type.generic_indicator) - { - generic_indicator gi = sil.FirstOrDefault().sym_info as generic_indicator; - AddError(loc, "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", names.names[names.names.Count - 1].name, gi.generic.generic_params.Count); - } - if (sil == null || sil.FirstOrDefault().sym_info == null) - { - check_possible_generic_names(names, loc); - } - var lastname = names.names[names.names.Count - 1]; - syntax_tree_node l = lastname; - while (l.source_context == null && l.Parent != null) - l = l.Parent; - - lastname.source_context = l?.source_context; - di = context.check_name_node_type(lastname.name, sil?.FirstOrDefault(), get_location(lastname), general_node_type.type_node); - return (type_node)di; - } - - public void check_possible_generic_names(SyntaxTree.named_type_reference names, location loc) - { - string tmp = names.names[names.names.Count - 1].name; - int num; - string generic_name = compiler_string_consts.GetGenericTypeInformation(tmp, out num); - List counts; - bool found = NetHelper.NetHelper.generics_names.TryGetValue(generic_name.ToLower(), out counts); - if (found) - { - foreach (int k in counts) - { - names.names[names.names.Count - 1].name = generic_name + - compiler_string_consts.generic_params_infix + k.ToString(); - List sinfo = context.find_definition_node(names, loc); - if (sinfo != null) - { - names.names[names.names.Count - 1].name = tmp; - AddError(loc, "GENERIC_TYPE_{0}_NEEDS_{1}_GENERIC_PARAMETERS", generic_name, k); - break; - } - } - names.names[names.names.Count - 1].name = tmp; - } - } - - - public expression_node make_break_node(location call_location, params expression_node[] parameters) - { - if (parameters.Length != 0) - { - return null; - } - if (context.cycle_stack.Empty) - { - AddError(new BreakStatementWithoutComprehensiveCycle(call_location)); - } - statement_node sn = context.cycle_stack.top(); - switch (sn.semantic_node_type) - { - case semantic_node_type.while_node: - { - while_node wn = (while_node)sn; - return new while_break_node(wn, call_location); - } - case semantic_node_type.repeat_node: - { - repeat_node rn = (repeat_node)sn; - return new repeat_break_node(rn, call_location); - } - case semantic_node_type.for_node: - { - for_node fn = (for_node)sn; - return new for_break_node(fn, call_location); - } - case semantic_node_type.foreach_node: - { - foreach_node fn = (foreach_node)sn; - return new foreach_break_node(fn, call_location); - } - } - throw new CompilerInternalError("Undefined cycle type"); - } - - public expression_node make_continue_node(location call_location, params expression_node[] parameters) - { - if (parameters.Length != 0) - { - return null; - } - if (context.cycle_stack.Empty) - { - AddError(new ContinueStatementWithoutComprehensiveCycle(call_location)); - } - statement_node sn = context.cycle_stack.top(); - switch (sn.semantic_node_type) - { - case semantic_node_type.while_node: - { - while_node wn = (while_node)sn; - return new while_continue_node(wn, call_location); - } - case semantic_node_type.repeat_node: - { - repeat_node rn = (repeat_node)sn; - return new repeat_continue_node(rn, call_location); - } - case semantic_node_type.for_node: - { - for_node fn = (for_node)sn; - return new for_continue_node(fn, call_location); - } - case semantic_node_type.foreach_node: - { - foreach_node fn = (foreach_node)sn; - return new foreach_continue_node(fn, call_location); - } - } - throw new CompilerInternalError("Undefined cycle type"); - } - - public expression_node make_exit_node(location call_location, params expression_node[] parameters) - { - if (parameters.Length != 0) - { - return null; - } - if (!TreeConverter.SemanticRules.EnableExitProcedure) - AddError(new TreeConverter.UndefinedNameReference(TreeConverter.compiler_string_consts.exit_procedure_name, call_location)); - return new exit_procedure(call_location); - } - - public override void visit(SyntaxTree.inherited_message _inherited_message) - { - //throw new NotSupportedError(get_location(_inherited_message)); - var mot = motivation_keeper.motivation; - motivation_keeper.reset(); - - switch (mot) - { - case motivation.expression_evaluation: return_value(inherited_message_value_reciving(_inherited_message)); break; - //case motivation.symbol_info_reciving: return_symbol_value(blocks.find(_ident.name));break; - case motivation.address_receiving: - case motivation.semantic_node_reciving: AddError(get_location(_inherited_message), "CAN_NOT_ASSIGN_TO_LEFT_PART"); break; - } - } - - private expression_node current_catch_excep; - - public override void visit(SyntaxTree.try_stmt _try_stmt) - { - context.enter_code_block_without_bind(); - context.enter_exception_handlers(); - statement_node try_statements = convert_strong(_try_stmt.stmt_list); - context.leave_code_block(); - location loc = get_location(_try_stmt); - exception_filters_list efl = new exception_filters_list(); - SyntaxTree.try_handler_except try_hand_except = _try_stmt.handler as SyntaxTree.try_handler_except; - if (try_hand_except != null) - { - if (try_hand_except.except_block.handlers != null) - { - int hand_count = try_hand_except.except_block.handlers.handlers.Count; - for (int i = 0; i < hand_count; i++) - { - SyntaxTree.exception_handler eh = try_hand_except.except_block.handlers.handlers[i]; - type_node filter_type = convert_strong(eh.type_name); - if (!SemanticRules.GenerateNativeCode && !(filter_type.is_generic_parameter || - filter_type == SystemLibrary.SystemLibrary.exception_base_type || - type_table.is_derived(SystemLibrary.SystemLibrary.exception_base_type, filter_type))) - { - AddError(get_location(eh.type_name), "EXCEPTION_TYPE_MUST_BE_SYSTEM_EXCEPTION_OR_DERIVED_FROM_EXCEPTION"); - } - current_catch_excep = new int_const_node(2,null);//create_constructor_call(filter_type, new expressions_list(), null); - local_block_variable_reference lvr = null; - statements_list sl = new statements_list(get_location(eh.statements)); - convertion_data_and_alghoritms.statement_list_stack_push(sl); - context.enter_code_block_without_bind(); - if (eh.variable != null) - { - local_block_variable lbv = context.add_var_definition(eh.variable.name, get_location(eh.variable), filter_type, SemanticTree.polymorphic_state.ps_common, true) as local_block_variable; - lvr = new local_block_variable_reference(lbv, lbv.loc); - } - statement_node stm = convert_strong(eh.statements); - context.leave_code_block(); - sl = convertion_data_and_alghoritms.statement_list_stack.pop(); - if (sl.statements.Count > 0 || sl.local_variables.Count > 0) - { - sl.statements.AddElement(stm); - stm = sl; - } - - exception_filter ef = new exception_filter(filter_type, lvr, stm, get_location(eh)); - efl.AddElement(ef); - current_catch_excep = null; - } - } - else - { - context.enter_code_block_without_bind(); - exception_filter ef = new exception_filter(null, null, convert_strong(try_hand_except.except_block.stmt_list), get_location(try_hand_except.except_block.stmt_list)); - context.leave_code_block(); - efl.AddElement(ef); - } - if (try_hand_except.except_block.else_stmt_list != null) - { - context.enter_code_block_without_bind(); - statement_node else_stm = convert_strong(try_hand_except.except_block.else_stmt_list); - context.leave_code_block(); - type_node ftype = SystemLibrary.SystemLibrary.object_type; - exception_filter else_ef = new exception_filter(ftype, null, else_stm, else_stm.location); - efl.AddElement(else_ef); - } - } - else - { - type_node filter_type = compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.ExceptionName)); - expression_node current_catch_excep = create_constructor_call(filter_type, new expressions_list(), null); - local_block_variable_reference lvr = null; - local_block_variable tmp_var = context.add_var_definition(context.BuildName("$try_temp" + UniqueNumStr()), null, SystemLibrary.SystemLibrary.bool_type, null) as local_block_variable; - statements_list stm = new statements_list(null); - SyntaxTree.try_handler_finally try_hndlr_finally = _try_stmt.handler as SyntaxTree.try_handler_finally; - context.enter_code_block_without_bind(); - statement_node finally_stmt = convert_strong(try_hndlr_finally.stmt_list); - context.leave_code_block(); - stm.statements.AddElement(finally_stmt); - - basic_function_call bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,null); - bfc.parameters.AddElement(new local_block_variable_reference(tmp_var,null)); - stm.statements.AddElement(new if_node(bfc,new rethrow_statement_node(null),null,null)); - exception_filter ef = new exception_filter(filter_type, lvr, stm, null); - //efl.AddElement(ef); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,null); - bfc.parameters.AddElement(new local_block_variable_reference(tmp_var,null)); - bfc.parameters.AddElement(new bool_const_node(true,null)); - - //(try_statements as statements_list).statements.AddElement(bfc); - //(try_statements as statements_list).statements.AddElement(new throw_statement_node(current_catch_excep,null)); - return_value(new try_block(try_statements, finally_stmt, efl, loc)); - context.leave_exception_handlers(); - return; - } - statement_node finally_st = null; - SyntaxTree.try_handler_finally try_handler_finally = _try_stmt.handler as SyntaxTree.try_handler_finally; - if (try_handler_finally != null) - { - context.enter_code_block_without_bind(); - finally_st = convert_strong(try_handler_finally.stmt_list); - context.leave_code_block(); - } - try_block tb = new try_block(try_statements, finally_st, efl, loc); - context.leave_exception_handlers(); - return_value(tb); - } - - public override void visit(SyntaxTree.try_handler_except _try_handler_except) - { - throw new NotSupportedError(get_location(_try_handler_except)); - } - - public override void visit(SyntaxTree.try_handler_finally _try_handler_finally) - { - throw new NotSupportedError(get_location(_try_handler_finally)); - } - - public override void visit(SyntaxTree.try_handler _try_handler) - { - throw new NotSupportedError(get_location(_try_handler)); - } - - public override void visit(SyntaxTree.exception_block _exception_block) - { - throw new NotSupportedError(get_location(_exception_block)); - } - - public override void visit(SyntaxTree.exception_handler_list _exception_handler_list) - { - throw new NotSupportedError(get_location(_exception_handler_list)); - } - - public override void visit(SyntaxTree.exception_ident _exception_ident) - { - throw new NotSupportedError(get_location(_exception_ident)); - } - - public override void visit(SyntaxTree.exception_handler _exception_handler) - { - throw new NotSupportedError(get_location(_exception_handler)); - } - - public override void visit(SyntaxTree.known_type_ident _known_type_ident) - { - if (_known_type_ident.type == PascalABCCompiler.SyntaxTree.known_type.string_type) - { - var mot = motivation_keeper.motivation; - motivation_keeper.reset(); - switch (mot) - { - case motivation.address_receiving: return_value(SystemLibrary.SystemLibrary.string_type); break; - case motivation.expression_evaluation: return_value(SystemLibrary.SystemLibrary.string_type); break; - //case motivation.symbol_info_reciving: return_symbol_value(blocks.find(_ident.name));break; - case motivation.semantic_node_reciving: return_semantic_value(SystemLibrary.SystemLibrary.string_type); break; - } - - return; - } - //throw new NotSupportedError(get_location(_known_type_ident)); - } - - public override void visit(SyntaxTree.file_type _file_type) - { - if (_file_type.file_of_type != null) - { - //Типизированый файл - type_node el_type = convert_strong(_file_type.file_of_type); - check_for_type_allowed(el_type,get_location(_file_type.file_of_type)); - check_using_static_class(el_type, get_location(_file_type.file_of_type)); - //if (el_type == SystemLibrary.SystemLibrary.void_type) - // ErrorsList.Add(new VoidNotValid(get_location(_file_type.file_of_type))); - /*if (el_type == SystemLibrary.SystemLibInitializer.TextFileType.sym_info) - { - //Это текстовый файл!!! - return_value(el_type); - return; - }*/ - if (SystemLibrary.SystemLibInitializer.TypedFileType == null || SystemLibrary.SystemLibInitializer.TypedFileInitProcedure == null) - AddError(new NotSupportedError(get_location(_file_type))); - if (!CanUseThisTypeForTypedFiles(el_type)) - AddError(get_location(_file_type.file_of_type), "INVALID_ELEMENT_TYPE_FOR_TYPED_FILE", el_type); - return_value(context.create_typed_file_type(el_type, get_location(_file_type))); - } - else - { - //Бинарнай файл - if (SystemLibrary.SystemLibInitializer.BinaryFileType == null) - AddError(new NotSupportedError(get_location(_file_type))); - ((type_node)SystemLibrary.SystemLibInitializer.BinaryFileType.sym_info).type_special_kind = SemanticTree.type_special_kind.binary_file; - return_value((type_node)SystemLibrary.SystemLibInitializer.BinaryFileType.sym_info); - } - } - - private bool CanUseThisTypeForFiles (type_node el_type, bool allow_strings) - { - if (el_type.is_generic_parameter) - { - if (SemanticRules.AllowGenericParametersForFiles) - { - if (allow_strings) - get_type_abilities(el_type).useful_for_binary_files = true; - else - get_type_abilities(el_type).useful_for_typed_files = true; - return true; - } - else - { - return false; - } - } - if (el_type.type_special_kind == SemanticTree.type_special_kind.short_string) - return true; - if (el_type.type_special_kind == SemanticTree.type_special_kind.set_type) - { - if (el_type.element_type == SystemLibrary.SystemLibrary.byte_type || el_type.element_type == SystemLibrary.SystemLibrary.sbyte_type - || el_type.element_type == SystemLibrary.SystemLibrary.bool_type || el_type.element_type.IsEnum) return true; - else if (el_type.element_type.type_special_kind == SemanticTree.type_special_kind.diap_type) - { - if (el_type.element_type.base_type == SystemLibrary.SystemLibrary.byte_type || el_type.element_type.base_type == SystemLibrary.SystemLibrary.sbyte_type - || el_type.element_type.base_type == SystemLibrary.SystemLibrary.bool_type || el_type.element_type.base_type.IsEnum) return true; - if (el_type.element_type.base_type == SystemLibrary.SystemLibrary.integer_type) - { - ordinal_type_interface oti = el_type.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; - if (((oti.upper_value as int_const_node).constant_value-(oti.lower_value as int_const_node).constant_value) <= 256) - return true; - } - - return false; - } - return false; - } - if (el_type.is_value) - { - generic_instance_type_node gitn = el_type as generic_instance_type_node; - if (gitn != null) - { - List ftypes = gitn.all_field_types; - foreach (type_node ftype in ftypes) - { - if (!CanUseThisTypeForFiles(ftype, allow_strings)) - return false; - } - return true; - } - if (SystemLibrary.SystemLibrary.CanUseThisTypeForTypedFiles(el_type)) - return true; - if (el_type is common_type_node) - { - if (el_type as common_type_node == context.converted_type || - (el_type.original_generic != null && el_type.original_generic == context.converted_type)) - return false; - common_type_node ctn = el_type as common_type_node; - foreach (class_field cf in ctn.fields) - if (!cf.IsStatic) - if (cf.type.type_special_kind != SemanticTree.type_special_kind.short_string && !CanUseThisTypeForFiles(cf.type, allow_strings)) - return false; - return true; - } - if (el_type is compiled_type_node) - { - compiled_type_node ctn = el_type as compiled_type_node; - if (!ctn.compiled_type.IsLayoutSequential) - return false; - System.Reflection.FieldInfo[] fields = ctn.compiled_type.GetFields(); - foreach (System.Reflection.FieldInfo fi in fields) - if (!fi.IsStatic) - if (!CanUseThisTypeForFiles(compiled_type_node.get_type_node(fi.FieldType), allow_strings)) - return false; - return true; - } - } - if (IsBoundedArray(el_type)) - { - //это обычный массив - bounded_array_interface bai = (bounded_array_interface)el_type.get_internal_interface(internal_interface_kind.bounded_array_interface); - return CanUseThisTypeForFiles(bai.element_type, allow_strings); - } - if (allow_strings && el_type == SystemLibrary.SystemLibrary.string_type) - { - return true; - } - return false; - } - - private bool CanUseThisTypeForTypedFiles(type_node el_type) - { - if (el_type.type_special_kind == SemanticTree.type_special_kind.short_string) return true; - return CanUseThisTypeForFiles(el_type, false); - } - - private bool CanUseThisTypeForBinaryFiles(type_node el_type) - { - if (el_type == SystemLibrary.SystemLibrary.string_type || el_type is short_string_type_node) return true; - return CanUseThisTypeForFiles(el_type, true); - } - - internal List get_short_string_lens(type_node tn) - { - List lst = new List(); - if (tn.type_special_kind == SemanticTree.type_special_kind.short_string) - { - lst.Add((tn as short_string_type_node).Length); - } - if (tn is common_type_node) - { - common_type_node ctn = tn as common_type_node; - if (ctn.type_special_kind == SemanticTree.type_special_kind.array_wrapper) - { - lst.AddRange(get_short_string_lens(ctn.element_type)); - } - else if (ctn.type_special_kind == SemanticTree.type_special_kind.record) - { - foreach (class_field fld in ctn.fields) - lst.AddRange(get_short_string_lens(fld.type)); - } - } - return lst; - } - - internal int get_short_string_size(type_node tn) - { - if (tn.type_special_kind == SemanticTree.type_special_kind.short_string) - { - return (tn as short_string_type_node).Length+1; - } - if (tn is common_type_node) - { - common_type_node ctn = tn as common_type_node; - if (ctn.type_special_kind == SemanticTree.type_special_kind.array_wrapper) - { - int len = ((ctn.find_first_in_type(compiler_string_consts.internal_array_name).sym_info as class_field).type as simple_array).length; - return len*get_short_string_size(ctn.element_type); - } - else if (ctn.type_special_kind == SemanticTree.type_special_kind.record) - { - int off = 0; - foreach (class_field fld in ctn.fields) - off += get_short_string_size(fld.type); - return off; - } - return 0; - } - return 0; - } - - internal expression_node get_init_call_for_typed_file(var_definition_node vdn, type_node element_type) - { - location loc = (vdn.type as common_type_node).loc; - if (!SystemUnitAssigned) - AddError(new NotSupportedError(loc)); - //Когда заработает наследование конструкторов надо вставить это - /* - expression_node var_ref = create_variable_reference(vdn, loc); - expressions_list exl = new expressions_list(); - exl.AddElement(new typeof_operator(element_type, loc)); - base_function_call bfc = create_constructor_call(vdn.type, exl, loc); - expression_node expr = find_operator(compiler_string_consts.assign_name, var_ref, bfc, loc); - */ - - type_node tn = vdn.type; - vdn.type = SystemLibrary.SystemLibInitializer.TypedFileType.sym_info as type_node; - - expression_node var_ref = create_variable_reference(vdn, loc); - expressions_list exl = new expressions_list(); - exl.AddElement(var_ref); - exl.AddElement(new typeof_operator(element_type, loc)); - List lens = get_short_string_lens(element_type); - int sz = get_short_string_size(element_type); - if (sz > 0) - { - exl.AddElement(new int_const_node(get_short_string_size(element_type),null)); - for (int i=0; i 1) - fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.TypedSetInitProcedureWithBounds.SymbolInfo, loc); - else - fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.TypedSetInitProcedure.SymbolInfo, loc); - expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, null, exl.ToArray()); - - vdn.type = tn; - - return expr; - } - - internal expression_node get_init_call_for_set_as_constr(var_definition_node vdn, expression_node init_value) - { - location loc = (vdn.type as common_type_node).loc; - if (!SystemUnitAssigned) - AddError(new NotSupportedError(loc)); - //Когда заработает наследование конструкторов надо вставить это - /* - expression_node var_ref = create_variable_reference(vdn, loc); - expressions_list exl = new expressions_list(); - exl.AddElement(new typeof_operator(element_type, loc)); - base_function_call bfc = create_constructor_call(vdn.type, exl, loc); - expression_node expr = find_operator(compiler_string_consts.assign_name, var_ref, bfc, loc); - */ - - type_node tn = vdn.type; - vdn.type = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node; - - expression_node var_ref = create_variable_reference(vdn, loc); - expressions_list exl = new expressions_list(); - //exl.AddElement(var_ref); - //exl.AddElement(new typeof_operator(element_type, loc)); - if (tn.element_type == SystemLibrary.SystemLibrary.byte_type) - { - exl.AddElement(new byte_const_node(byte.MinValue,null)); - exl.AddElement(new byte_const_node(byte.MaxValue,null)); - } - else if (tn.element_type == SystemLibrary.SystemLibrary.sbyte_type) - { - exl.AddElement(new sbyte_const_node(sbyte.MinValue,null)); - exl.AddElement(new sbyte_const_node(sbyte.MaxValue,null)); - } - else if (tn.element_type == SystemLibrary.SystemLibrary.short_type) - { - exl.AddElement(new short_const_node(short.MinValue,null)); - exl.AddElement(new short_const_node(short.MaxValue,null)); - } - else if (tn.element_type == SystemLibrary.SystemLibrary.ushort_type) - { - exl.AddElement(new ushort_const_node(ushort.MinValue,null)); - exl.AddElement(new ushort_const_node(ushort.MaxValue,null)); - } - else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.diap_type || tn.element_type.type_special_kind == SemanticTree.type_special_kind.enum_kind) - { - ordinal_type_interface ii = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; - exl.AddElement(ii.lower_value); - exl.AddElement(ii.upper_value); - } - exl.AddElement(init_value); - function_node fn = null; - if (exl.Count > 1) - { - fn = convertion_data_and_alghoritms.select_function(exl, (SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node).find_in_type(compiler_string_consts.default_constructor_name), loc); - } - else - { - fn = convertion_data_and_alghoritms.select_function(exl, (SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node).find_in_type(compiler_string_consts.default_constructor_name), loc); - } - //expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, null, exl.ToArray()); - expression_node expr = create_static_method_call_with_params(fn, loc, tn, false, exl); - vdn.type = tn; - - return expr; - } - - internal expression_node get_init_call_for_short_string(var_definition_node vdn) - { - location loc = (vdn.type as short_string_type_node).loc; - - type_node tn = vdn.type; - //vdn.type = SystemLibrary.SystemLibInitializer.ShortStringType.TypeNode; - vdn.type = SystemLibrary.SystemLibrary.string_type; - int Length = (tn as short_string_type_node).Length; - - expression_node var_ref = create_variable_reference(vdn, loc); - expressions_list exl = new expressions_list(); - exl.AddElement(var_ref); - exl.AddElement(new int_const_node(Length, loc)); - expression_node expr = null; - //if (SystemLibrary.SystemLibInitializer.ShortStringTypeInitProcedure != null) - //convertion_data_and_alghoritms.create_full_function_call(exl, SystemLibrary.SystemLibInitializer.ShortStringTypeInitProcedure.SymbolInfo, null, context.converted_type, context.top_function, true); - - vdn.type = tn; - - return expr; - } - - - public override void visit(SyntaxTree.op_type_node _op_type_node) - { - throw new NotSupportedError(get_location(_op_type_node)); - } - - public override void visit(SyntaxTree.raise_stmt _raise_stmt) - { - location loc = get_location(_raise_stmt); - if (_raise_stmt.expr == null) - { - var st = _raise_stmt.Parent; - while (st != null && !(st is exception_block)) - { - st = st.Parent; - } - //if (current_catch_excep == null) - if (st == null) - AddError(loc, "RAISE_WITHOUT_PARAMETERS_MUST_BE_IN_CATCH_BLOCK"); - return_value(new rethrow_statement_node(loc)); - return; - } - expression_node en = convert_strong(_raise_stmt.expr); - if (en is typed_expression) en = convert_typed_expression_to_function_call(en as typed_expression); - if (!SemanticRules.GenerateNativeCode && (!(type_table.is_derived(SystemLibrary.SystemLibrary.exception_base_type, en.type))) && - (en.type != SystemLibrary.SystemLibrary.exception_base_type)) - { - AddError(loc, "EXCEPTION_TYPE_MUST_BE_SYSTEM_EXCEPTION_OR_DERIVED_FROM_EXCEPTION"); - } - if (_raise_stmt.address != null) - { - AddError(new NotSupportedError(get_location(_raise_stmt.address))); - } - return_value(new throw_statement_node(en, loc)); - } - - public override void visit(SyntaxTree.token_info _token_info) - { - throw new NotSupportedError(get_location(_token_info)); - } - - public override void visit(SyntaxTree.initfinal_part _initfinal_part) - { - } - - private bool is_format_allowed=false; - - public override void visit(SyntaxTree.format_expr _format_expr) - { - if (_format_expr.expr == null || _format_expr.format1 == null) - AddError(get_location(_format_expr), "BAD_CONSTRUCTED_FORMAT_EXPRESSION"); - //TODO: Добавить проверки. - if (!SemanticRules.AllowUseFormatExprAnywhere && !is_format_allowed) - AddError(get_location(_format_expr.expr), "FORMAT_EXPRESSION_CAN_USE_ONLY_IN_THESE_PROCEDURES"); - expression_node expr = convert_strong(_format_expr.expr); - if (expr is typed_expression) - expr = convert_typed_expression_to_function_call(expr as typed_expression); - expression_node par1 = convert_strong(_format_expr.format1); - par1 = convertion_data_and_alghoritms.convert_type(par1, SystemLibrary.SystemLibrary.integer_type); - expression_node par2 = convert_weak(_format_expr.format2); - if (par2 != null) - { - if (expr.type != SystemLibrary.SystemLibrary.double_type && expr.type != SystemLibrary.SystemLibrary.float_type) - { - AddError(expr.location, "REAL_TYPE_IN_DOUBLE_COLON_EXPRESSION_EXPECTED"); - } - par2 = convertion_data_and_alghoritms.convert_type(par2, SystemLibrary.SystemLibrary.integer_type); - } - expressions_list exl = new expressions_list(); - exl.AddElement(expr); - exl.AddElement(par1); - if (par2 != null) - { - exl.AddElement(par2); - } - location loc = get_location(_format_expr); - if (!SystemUnitAssigned) - AddError( new NotSupportedError(loc)); - function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.format_function.SymbolInfo, - loc); - expression_node ret = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, exl.ToArray()); - return_value(ret); - } - - internal bool inherited_ident_processing = false; - public override void visit(SyntaxTree.inherited_ident _inherited_ident) - { - inherited_ident_processing = true; - var mot = motivation_keeper.motivation; - motivation_keeper.reset(); - switch (mot) - { - case motivation.address_receiving: return_addressed_value(inherited_ident_address_reciving(_inherited_ident)); break; - case motivation.expression_evaluation: return_value(inherited_ident_value_reciving(_inherited_ident)); break; - //case motivation.symbol_info_reciving: return_symbol_value(blocks.find(_ident.name));break; - case motivation.semantic_node_reciving: return_semantic_value(inherited_ident_semantic_reciving(_inherited_ident)); break; - } - inherited_ident_processing = false; - return; - } - - public override void visit(SyntaxTree.property_parameter_list _property_parameter_list) - { - throw new NotSupportedError(get_location(_property_parameter_list)); - } - - public override void visit(SyntaxTree.property_parameter _property_parameter) - { - throw new NotSupportedError(get_location(_property_parameter)); - } - - public override void visit(SyntaxTree.property_interface _property_interface) - { - //throw new NotSupportedError(get_location(_property_interface)); - } - - public override void visit(SyntaxTree.property_array_default _property_array_default) - { - throw new NotSupportedError(get_location(_property_array_default)); - } - - public override void visit(SyntaxTree.record_type_parts _record_type_parts) - { - throw new NotSupportedError(get_location(_record_type_parts)); - } - - public override void visit(SyntaxTree.var_def_list_for_record _var_def_list) - { - throw new NotSupportedError(get_location(_var_def_list)); - } - - public override void visit(SyntaxTree.diapason_expr _diapason_expr) - { - throw new NotSupportedError(get_location(_diapason_expr)); - } - - public override void visit(SyntaxTree.case_variants _case_variants) - { - throw new NotSupportedError(get_location(_case_variants)); - } - - public override void visit(SyntaxTree.literal _literal) - { - throw new NotSupportedError(get_location(_literal)); - } - - public override void visit(SyntaxTree.array_of_const_type_definition _array_of_const_type_definition) - { - throw new NotSupportedError(get_location(_array_of_const_type_definition)); - } - - public override void visit(SyntaxTree.array_of_named_type_definition _array_of_named_type_definition) - { - throw new NotSupportedError(get_location(_array_of_named_type_definition)); - } - - public override void visit(SyntaxTree.proc_block _proc_block) - { - throw new NotSupportedError(get_location(_proc_block)); - } - - private statements_list get_statements_list(statement_node sn) - { - statements_list snl = sn as statements_list; - if (snl != null) - { - return snl; - } - snl = new statements_list(null); - snl.statements.AddElement(sn); - return snl; - } - - private statements_list add_first_statement(statement_node list, statement_node statement) - { - statements_list snl = get_statements_list(list); - snl.statements.AddElementFirst(statement); - return snl; - } - - private statements_list add_last_statement(statement_node list, statement_node statement) - { - statements_list snl = get_statements_list(list); - snl.statements.AddElement(statement); - return snl; - } - - public override void visit(SyntaxTree.block _block) - { - var tt = context.converting_block(); - List declarations_with_lambdas = new List(); - if (/*context.converting_block() != block_type.namespace_block && */_block.defs != null && _block.defs.defs != null) - { - foreach (var def in _block.defs.defs.Where(d => d is const_definition || - d is consts_definitions_list || - d is variable_definitions)) - { - var lambdaSearcher = new LambdaSearcher(def); - if (lambdaSearcher.CheckIfContainsLambdas()) - { - if (context.converting_block() != block_type.namespace_block || !(def is variable_definitions)) - AddError(new LambdasNotAllowedInDeclarationsSection(get_location(lambdaSearcher.FoundLambda))); // SSM 6.06.15 - Хочется убрать это. В разделе описаний лямбды нужны - пусть и без замыканий. Если внутри подпрограммы - не нужны, но Вы же запретили везде! - else - declarations_with_lambdas.Add(def as variable_definitions); - } - } - } - int lambda_init_index = 0; - foreach (variable_definitions vd in declarations_with_lambdas) - { - foreach (var_def_statement vds in vd.list) - { - var lambdaSearcher = new LambdaSearcher(vds); - if (lambdaSearcher.CheckIfContainsLambdas() && !(vds.inital_value is function_lambda_definition) && vds.inital_value != null) // SSM 27/10/17 - { - procedure_definition func = - new short_func_definition( - SyntaxTreeBuilder.BuildShortFuncDefinition(new formal_parameters(), new procedure_attributes_list(), new method_name("<>lambda_initializer" + lambda_init_index), null, vds.inital_value, null)); - - vds.inital_value = new method_call(new ident("<>lambda_initializer"+lambda_init_index), new expression_list()); - _block.defs.InsertBefore(vd, func); - lambda_init_index++; - } - } - } - if (context.converting_block() == block_type.function_block && context.converted_func_stack.size == 1) - { - if (_block.defs != null) - foreach (declaration decl in _block.defs.defs) - { - if (decl is procedure_definition) - { - context.has_nested_functions = true; - break; - } - } - } - weak_node_test_and_visit(_block.defs); - if (context.converting_block() == block_type.function_block && context.converted_func_stack.size == 1) - context.has_nested_functions = false; - //ssyy добавил генерацию вызова конструктора предка без параметров - if (context.converting_block() == block_type.function_block) - { - common_method_node cmn = context.top_function as common_method_node; - if (cmn != null && cmn.is_constructor && !(cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)) - { - context.allow_inherited_ctor_call = true; - if (_block.program_code != null && _block.program_code.subnodes != null) - { - //(ssyy) Для записей конструктор предка не вызываем. - bool should_ctor_add = context.converted_type.is_class; - if (should_ctor_add) - { - if (_block.program_code.subnodes.Count > 0) - { - SyntaxTree.procedure_call pc = _block.program_code.subnodes[0] as SyntaxTree.procedure_call; - if (pc != null || _block.program_code.subnodes[0] is SyntaxTree.inherited_message) - { - //SyntaxTree.inherited_ident ii = pc.func_name as SyntaxTree.inherited_ident; - //SyntaxTree.method_call mc = pc.func_name as SyntaxTree.method_call; - //SyntaxTree.ident id = pc.func_name as SyntaxTree.ident; - //if (/*ii != null*/id != null || mc != null /*&& mc.dereferencing_value is SyntaxTree.inherited_ident*/) - { - //(ssyy) Не уверен, что следующий оператор необходим. - convertion_data_and_alghoritms.check_node_parser_error(_block.program_code); - var lambdaSearcher = new LambdaSearcher(_block.program_code.subnodes[0]); - if (!lambdaSearcher.CheckIfContainsLambdas()) - { - statement_node inh = convert_strong(_block.program_code.subnodes[0]); - - compiled_constructor_call c1 = inh as compiled_constructor_call; - if (c1 != null && !c1._new_obj_awaited) - { - should_ctor_add = false; - } - else - { - common_constructor_call c2 = inh as common_constructor_call; - if (c2 != null && !c2._new_obj_awaited) - { - should_ctor_add = false; - } - } - } - - } - } - } - } - if (should_ctor_add) - { - //Пытаемся добавить вызов .ctor() предка... - //Для начала проверим, есть ли у предка таковой. - bool not_found = true; - List sym = context.converted_type.base_type.find_in_type(compiler_string_consts.default_constructor_name, context.CurrentScope); - if (sym != null) - { - foreach (SymbolInfo sym_unit in sym) - { - if (!not_found) - break; - compiled_constructor_node ccn = sym_unit.sym_info as compiled_constructor_node; - if (ccn != null && ccn.parameters.Count == 0) - { - not_found = false; - } - else - { - common_method_node cnode = sym_unit.sym_info as common_method_node; - if (cnode != null && cnode.is_constructor && (cnode.parameters.Count == 0 || cnode.parameters[0].default_value != null)) - { - not_found = false; - } - } - } - } - if (not_found) - { - var l = get_location(_block.program_code); - if (l == null) - { - AddError(cmn.return_value_type.location, "IN_AUTOGENERATED_DEFAULT_CONSTRUCTOR_THE_DEFAULT_CONSTRUCTOR_OF_BASE_CLASS_CANNOT_BE_CALLED_BECAUSE_IS_ABSENT_OR_PRIVATE"); - } - //У предка нет конструктора по умолчанию - AddError(l, "INHERITED_CONSTRUCTOR_CALL_EXPECTED"); - } - else - { - //Генерируем вызов .ctor() предка - SyntaxTree.inherited_ident ii = new SyntaxTree.inherited_ident(); - ii.name = compiler_string_consts.default_constructor_name; - _block.program_code.subnodes.Insert(0, new SyntaxTree.procedure_call(ii)); - //context.allow_inherited_ctor_call = false; - } - } - } - } - } - //\ssyy - - //ssyy - if (context.converting_block() == block_type.namespace_block) - { - context.check_predefinition_defined(); - } - - if (lambdaProcessingState == LambdaProcessingState.None && _block.program_code != null) - { - var lambdaSearcher = new LambdaSearcher(_block.program_code); - var lambdaIsFound = lambdaSearcher.CheckIfContainsLambdas(); - - if ((context.converting_block() == block_type.function_block || - context.converting_block() == block_type.namespace_block) && - lambdaIsFound) - // TODO: Пока обрабатываются только блок функции и основной блок, необходимо обрабатывать случаи появлений лямбд в var_def_statement - { - if (context.converting_block() == block_type.function_block) - { - if (context.func_stack.top().functions_nodes_list.Count > 0) - { - AddError(new LambdasNotAllowedWhenNestedSubprogrammesAreUsed(get_location(lambdaSearcher.FoundLambda))); - } - } - - lambdaProcessingState = LambdaProcessingState.TypeInferencePhase; - visit_program_code(_block.program_code); - - // Очистили списки goto для меток перед следующим этапом - пока ничего не дало - закомментируем - foreach (var l in context._cmn.labels) - { - l.goto_statements.Clear(); - l.comprehensive_code_block = null; - } - if (context.func_stack.size > 0) - { - var fun = context.func_stack.top(); - foreach (var l in fun.label_nodes_list) - { - l.goto_statements.Clear(); - l.comprehensive_code_block = null; - } - } - - // Грубо - удаление мусора при разборе лямбд. Происходит исключение - заголовок разбирается, тело остается пустым - и из-за этого была ошибка #1270. - while (context._cmn.functions.Count > 0 && context._cmn.functions[context._cmn.functions.Count-1].function_code == null && context._cmn.functions[context._cmn.functions.Count - 1].name.StartsWith("<>lambda") && !context._cmn.functions[context._cmn.functions.Count - 1].name.StartsWith("<>lambda_initializer")) - { -#if DEBUG - //System.IO.File.AppendAllText("aa.txt", context._cmn.functions[context._cmn.functions.Count - 1].name+"\n"); -#endif - context._cmn.functions.remove_at(context._cmn.functions.Count - 1); - - } - - lambdaProcessingState = LambdaProcessingState.ClosuresProcessingPhase; - CapturedVariablesSubstitutionsManager.Substitute(this, _block.defs, _block.program_code); - - lambdaProcessingState = LambdaProcessingState.FinishPhase; - - context.code = visit_program_code(_block.program_code); - - lambdaProcessingState = LambdaProcessingState.None; - } - else - { - context.code = visit_program_code(_block.program_code); - } - } - else - { - context.code = visit_program_code(_block.program_code); - } - } - - private statement_node visit_program_code(statement_list program_code) - { - context.enter_code_block_with_bind(); - statement_node sn = convert_strong(program_code); - context.leave_code_block(); - - return sn; - } - - public override void visit(SyntaxTree.diap_expr _diap_expr) - { - throw new NotSupportedError(get_location(_diap_expr)); - } - internal SymbolTable.Scope[] build_referenced_units(unit_node_list referenced_units, bool try_get_system_module) - { - List used_units = new List(); - Dictionary assembly_references_dict = new Dictionary(); - for (int i = 0; i < referenced_units.Count; i++) - { - if (referenced_units[i] is dot_net_unit_node) - if (!assembly_references_dict.ContainsKey((referenced_units[i] as dot_net_unit_node).dotNetScope._assembly)) - assembly_references_dict.Add((referenced_units[i] as dot_net_unit_node).dotNetScope._assembly, referenced_units[i] as dot_net_unit_node); - } - dot_net_unit_node[] assembly_references = new dot_net_unit_node[assembly_references_dict.Values.Count]; - assembly_references_dict.Values.CopyTo(assembly_references, 0); - List def_scopes = new List(); - if (SemanticRules.AllowGlobalVisibilityForPABCDll) - { - for (int i = 0; i < assembly_references.Length; i++) - { - if (assembly_references[i].dotNetScope.entry_type != null) - def_scopes.Add(assembly_references[i].dotNetScope); - } - } - //used_units.Add(_system_unit.scope); - for (int i = 0; i < referenced_units.Count; i++) - { - if (!(referenced_units[i] is dot_net_unit_node)) - { - if (referenced_units[i] is namespace_unit_node) - { - namespace_unit_node nun = referenced_units[i] as namespace_unit_node; - for (int j = 0; j < assembly_references.Length; j++) - { - using_namespace_list unl = new using_namespace_list(); - unl.AddElement((referenced_units[i] as namespace_unit_node).namespace_name); - NetHelper.NetScope ns = new PascalABCCompiler.NetHelper.NetScope(unl, assembly_references[j].dotNetScope._assembly, SymbolTable); - used_units.Add(ns); - } - if (_compiled_unit != null) - _compiled_unit.used_namespaces.Add((referenced_units[i] as namespace_unit_node).namespace_name.namespace_name); - if (nun.scope != null) - used_units.Add(nun.scope); - } - else - { - common_unit_node cun = referenced_units[i] as common_unit_node; - if (cun != null) - { - if (try_get_system_module && cun.IsSystemUnit) - { - get_system_module(cun); - for (int j = 0; j < def_scopes.Count; j++) - { - used_units.Add(new PascalABCCompiler.NetHelper.NetScope(interface_using_list, def_scopes[j]._assembly, SymbolTable)); - } - } - used_units.Add(cun.scope); - } - else - { - throw new CompilerInternalError("Unexpected unit type."); - } - } - } - else - { - dot_net_unit_node dun = referenced_units[i] as dot_net_unit_node; - if (dun.dotNetScope.entry_type != null && dun.dotNetScope.entry_type.Name == "PABCRtl") - { - if (try_get_system_module) - { - from_pabc_dll = true; - get_system_module_from_dll(dun); - } - } - } - } - List fetched_used_units = new List(); - Dictionary assm_cache = new Dictionary(); - for (int i = 0; i < used_units.Count; i++) - { - PascalABCCompiler.NetHelper.NetScope net_scope = used_units[i] as PascalABCCompiler.NetHelper.NetScope; - if (net_scope != null) - { - PascalABCCompiler.NetHelper.NetScope existing_scope = null; - if (assm_cache.TryGetValue(net_scope.Assembly, out existing_scope)) - { - /*if (net_scope.used_namespaces) - { - foreach (using_namespace un in net_scope.used_namespaces) - { - if (un.namespace_name) - } - }*/ - existing_scope.used_namespaces.AddRange(net_scope.used_namespaces); - } - else - { - if (NetHelper.NetHelper.PABCSystemType == null || net_scope.Assembly != NetHelper.NetHelper.PABCSystemType.Assembly) - assm_cache.Add(net_scope.Assembly, net_scope); - fetched_used_units.Add(net_scope); - } - } - else - fetched_used_units.Add(used_units[i]); - } - used_units = fetched_used_units; - //Если компилими implementation то в начало кладем все что было в interface - for (int i = 0; i < assembly_references.Length; i++) - { - used_units.Add(new PascalABCCompiler.NetHelper.NetScope(interface_using_list, (assembly_references[i] as dot_net_unit_node).dotNetScope._assembly, SymbolTable)); - } - used_units.Add(_system_unit.scope); - - return used_units.ToArray(); - } - - - public void visit_implementation(SyntaxTree.unit_module _unit_module) - { - if (_unit_module.initialization_part != null) - { - var lambdaSearcher = new LambdaSearcher(_unit_module.initialization_part); - if (lambdaSearcher.CheckIfContainsLambdas()) - { - AddError(new LambdasNotAllowedInInitializationPartOfModule(get_location(lambdaSearcher.FoundLambda))); - } - } - - if (_unit_module.finalization_part != null) - { - var lambdaSearcher = new LambdaSearcher(_unit_module.finalization_part); - if (lambdaSearcher.CheckIfContainsLambdas()) - { - AddError(new LambdasNotAllowedInFinalizationPartOfModule(get_location(lambdaSearcher.FoundLambda))); - } - } - - //using_list.AddRange(implementation_using_list); - /*if (_unit_module.implementation_part != null) - { - weak_node_test_and_visit(_unit_module.implementation_part.using_namespaces); - }*/ - - SymbolTable.Scope[] used_units = build_referenced_units(referenced_units,false); - - _compiled_unit.implementation_scope = - convertion_data_and_alghoritms.symbol_table.CreateUnitImplementationScope(_compiled_unit.scope, used_units); - - location loc = null; - if (_unit_module.unit_name != null) - { - loc = get_location(_unit_module.unit_name); - } - - common_namespace_node cnsn = context.create_namespace(_unit_module.unit_name.idunit_name.name + compiler_string_consts.ImplementationSectionNamespaceName, - _compiled_unit, _compiled_unit.implementation_scope, loc); - - //cnsn.scope=_compiled_unit.implementation_scope; - - if (_unit_module.implementation_part != null) - { - hard_node_test_and_visit(_unit_module.implementation_part); - } - - //weak_node_test_and_visit(_unit_module.initialization_part); - context.enter_code_block_without_bind(); - - statement_node init_statements = convert_weak(_unit_module.initialization_part); - context.leave_code_block(); - common_namespace_function_node initialization_function = null; - if (init_statements != null) - { - context.check_labels(context.converted_namespace.labels); - //(ssyy) Блокируем поставленные метки, чтобы не допустить переход из finalization-секции - //context.block_defined_labels(context.converted_namespace.labels); - initialization_function = new common_namespace_function_node(compiler_string_consts.initialization_function_name, - null, init_statements.location, context.converted_namespace, convertion_data_and_alghoritms.symbol_table.CreateScope(context.converted_namespace.scope)); - initialization_function.function_code = init_statements; - cnsn.functions.AddElement(initialization_function); - _compiled_unit.main_function = initialization_function; - context.apply_special_local_vars(_compiled_unit.main_function); - } - - context.enter_code_block_without_bind(); - statement_node final_statements = convert_weak(_unit_module.finalization_part); - context.leave_code_block(); - common_namespace_function_node finalization_function = null; - if (final_statements != null) - { - context.check_labels(context.converted_namespace.labels); - finalization_function = new common_namespace_function_node(compiler_string_consts.finalization_function_name, - null, final_statements.location, context.converted_namespace, convertion_data_and_alghoritms.symbol_table.CreateScope(context.converted_namespace.scope)); - finalization_function.function_code = final_statements; - cnsn.functions.AddElement(finalization_function); - _compiled_unit.finalization_method = finalization_function; - context.apply_special_local_vars(_compiled_unit.finalization_method); - } - - context.check_all_name_unit_defined(_compiled_unit); - } - - public override void visit(SyntaxTree.implementation_node _implementation_node) - { - if (_implementation_node.implementation_definitions != null && _implementation_node.implementation_definitions.defs != null) - { - foreach (var def in _implementation_node.implementation_definitions.defs.Where(d => d is const_definition || - d is consts_definitions_list || - d is variable_definitions)) - { - var lambdaSearcher = new LambdaSearcher(def); - if (lambdaSearcher.CheckIfContainsLambdas()) - { - AddError(new LambdasNotAllowedInImplementationOfModuleInInit(get_location(lambdaSearcher.FoundLambda))); - } - } - } - - weak_node_test_and_visit(_implementation_node.implementation_definitions); - } - - bool in_interface_part = false; - - public override void visit(SyntaxTree.interface_node _interface_node) - { - if (_interface_node.interface_definitions != null && _interface_node.interface_definitions.defs != null) - { - foreach (var def in _interface_node.interface_definitions.defs.Where(d => d is const_definition || - d is consts_definitions_list || - d is variable_definitions)) - { - var lambdaSearcher = new LambdaSearcher(def); - if (lambdaSearcher.CheckIfContainsLambdas()) - { - AddError(new LambdasNotAllowedInInterfacePartOfModuleInInit(get_location(lambdaSearcher.FoundLambda))); - } - } - } - - weak_node_test_and_visit(_interface_node.interface_definitions); - } - - - public override void visit(SyntaxTree.typecast_node node) - { - - expression_node en = convert_strong(node.expr); - location loc = get_location(node); - type_node tp = convert_strong(node.type_def); - //ssyy - if (en.type.semantic_node_type == semantic_node_type.delegated_method) - { - try_convert_typed_expression_to_function_call(ref en); - } - //\ssyy - if (!SemanticRules.IsAsForPointers && (tp.IsPointer || en.type.IsPointer)) - { - if (node.cast_op == PascalABCCompiler.SyntaxTree.op_typecast.is_op) - AddError(loc, "OPERATOR_{0}_CAN_NOT_BE_APPLIED_TO_POINTER_TYPE", compiler_string_consts.is_name); - else - AddError(loc, "OPERATOR_{0}_CAN_NOT_BE_APPLIED_TO_POINTER_TYPE", compiler_string_consts.as_name); - } - else - if (!(type_table.is_derived(en.type, tp) || type_table.is_derived(tp, en.type) - || en.type == tp || en.type == SystemLibrary.SystemLibrary.object_type - || en.type.IsInterface || tp.IsInterface || tp.is_generic_parameter || en.type.is_generic_parameter) - ) - { - AddError(loc, "EXPECTED_DERIVED_CLASSES"); - } - if (en.type.IsSealed && tp.IsInterface && /*!en.type.ImplementingInterfaces.Contains(tp)*/ - !convertion_data_and_alghoritms.type_or_base_type_implements_interface(en.type,tp) - ) - { - AddError(loc, "CAN_NOT_CONVERT_TYPE_{0}_TO_INTERFACE_{1}", en.type.PrintableName, tp.PrintableName); - } - if (node.cast_op == PascalABCCompiler.SyntaxTree.op_typecast.is_op) - { - is_node isn = new is_node(en, tp, loc); - return_value(isn); - } - else - { - if (tp.is_generic_parameter && !tp.is_class && !(tp.base_type != null && tp.base_type.is_class) && !(tp.base_type != null && tp.base_type.original_generic != null && tp.base_type.original_generic.is_class)) - AddError(get_location(node.type_def), "OPERATOR_AS_CAN_NOT_BE_USED_WITH_GENERIC_PARAMETER_{0}_WITHOUT_CLASS_CONSTRAINT", tp.name); - if (tp.is_value_type) - AddError(get_location(node.type_def), "OPERATOR_AS_MUST_BE_USED_WITCH_A_REFERENCE_TYPE_VALUETYPE{0}", tp.PrintableName); - as_node asn = new as_node(en, tp, loc); - return_value(asn); - } - } - - public override void visit(SyntaxTree.inherited_method_call _inherited_method_call) - { - throw new NotSupportedError(get_location(_inherited_method_call)); - } - - public override void visit(SyntaxTree.destructor _destructor) - { - if (_destructor.name == null) - { - AddError(get_location(_destructor), "DESTRUCTOR_MUST_HAVE_NAME"); - } - if (context.converting_block() == block_type.type_block) - { - if (context.converted_type.IsInterface) - { - AddError(get_location(_destructor), "DESTRUCTOR_IN_INTERFACE"); - } - if (!context.converted_type.is_class) - { - AddError(get_location(_destructor), "DESTRUCTOR_NOT_IN_CLASS"); - } - } - else if (!(context.converting_block() == block_type.namespace_block && _destructor.name.class_name != null)) - { - AddError(get_location(_destructor), "DESTRUCTOR_NOT_IN_CLASS"); - } - if (_destructor.parameters != null && _destructor.parameters.params_list.Count > 0) - { - AddError(get_location(_destructor), "DESTRUCTOR_CANNOT_HAVE_PARAMETERS"); - } - visit_procedure_header(_destructor); - } - - //ssyy изменил этот метод из-за изменения концепции конструкторов - public override void visit(SyntaxTree.constructor _constructor) - { - if (context.converting_block() == block_type.type_block) - { - if (context.converted_type.IsInterface) - { - AddError(new ConstructorInInterface(get_location(_constructor))); - } - /*if (!context.converted_type.is_class) - { - throw new ConstructorNotInClass(get_location(_constructor)); - }*/ - } - else if (!(context.converting_block() == block_type.namespace_block && _constructor.name != null && _constructor.name.class_name != null)) - { - AddError(get_location(_constructor), "CONSTRUCTOR_NOT_IN_CLASS"); - } - - convertion_data_and_alghoritms.check_node_parser_error(_constructor.name); - - if (_constructor.name == null) - { - SyntaxTree.ident name = new SyntaxTree.ident(compiler_string_consts.default_constructor_name); - _constructor.name = new PascalABCCompiler.SyntaxTree.method_name(null, null, name, null); - _constructor.name.source_context = _constructor.name.meth_name.source_context = _constructor.source_context; - } - - if (_constructor.name.meth_name.name.ToLower() != compiler_string_consts.default_constructor_name) - AddError(get_location(_constructor.name), "CONSTRUCTOR_CAN_HAVE_ONLY_{0}_NAME", compiler_string_consts.default_constructor_name); - if ((_constructor.name.class_name == null) && (context.converting_block() != block_type.type_block)) - { - AddError(get_location(_constructor.name), "ONLY_CONSTRUCTOR_OF_TYPE_ALLOWED"); - } - - foreach (SyntaxTree.procedure_attribute att in _constructor.proc_attributes.proc_attributes) - { - if (att.attribute_type == SyntaxTree.proc_attribute.attr_virtual) - { - AddError(get_location(att), "CONSTRUCTOR_CAN_NOT_BE_VIRTUAL"); - } - else if (att.attribute_type == SyntaxTree.proc_attribute.attr_override) - { - AddError(get_location(att), "CONSTRUCTOR_CAN_NOT_BE_OVERRIDE"); - } - else if (att.attribute_type == SyntaxTree.proc_attribute.attr_abstract) - { - AddError(get_location(att), "CONSTRUCTOR_CANNOT_BE_ABSTRACT"); - } - } - if (_constructor.class_keyword) - { - SyntaxTree.procedure_attribute pa = new SyntaxTree.procedure_attribute(PascalABCCompiler.SyntaxTree.proc_attribute.attr_static); - pa.source_context = _constructor.source_context; - _constructor.proc_attributes.proc_attributes.Add(pa); - } - foreach (SyntaxTree.procedure_attribute att in _constructor.proc_attributes.proc_attributes) - { - if (att.attribute_type == SyntaxTree.proc_attribute.attr_static) - { - //Это статический конструктор - if (_constructor.parameters != null) - { - AddError(get_location(_constructor.name), "STATIC_CONSTRUCTOR_MUST_BE_PARAMETERLESS"); - } - _constructor.name.meth_name.name = compiler_string_consts.static_ctor_prefix + _constructor.name.meth_name.name; - visit_procedure_header(_constructor); - if (context.top_function != null) - { - (context.top_function as common_method_node).is_constructor = true; - (context.top_function as common_method_node).cont_type.static_constr = context.top_function as common_method_node; - } - return; - } - } - - if (context.converting_block() == block_type.type_block) - { - //Нужно для генерации унаследованных конструкторов - context.converted_type.has_user_defined_constructor = true; - - //Нужно для генерации конструктора по умолчанию - if (_constructor.parameters == null || _constructor.parameters.params_list[0].inital_value != null) - { - context.converted_type.has_default_constructor = true; - } - } - - visit_procedure_header(_constructor); - - if (context.top_function == null) - { - return; - } - common_method_node cmn = context.top_function as common_method_node; - - if (cmn == null) - { - throw new CompilerInternalError("Constructor is not common_method_node."); - } - - context.allow_inherited_ctor_call = true; - cmn.is_constructor = true; - cmn.return_value_type = context.converted_type; - } - - public override void visit(SyntaxTree.file_type_definition _file_type_definition) - { - throw new NotSupportedError(get_location(_file_type_definition)); - } - - public override void visit(SyntaxTree.nil_const _nil_const) - { - return_value(new null_const_node(null_type_node.get_type_node(), get_location(_nil_const))); - } - - public override void visit(SyntaxTree.class_predefinition _class_predefinition) - { - throw new NotSupportedError(get_location(_class_predefinition)); - } - - private bool statement_expected = false; - private bool procedure_wait = false; - - public override void visit(SyntaxTree.procedure_call _procedure_call) - { - procedure_wait = true; - SyntaxTree.method_call mc = null; - mc = _procedure_call.func_name as SyntaxTree.method_call; - if (mc == null) - { - SyntaxTree.ident id = _procedure_call.func_name as SyntaxTree.ident; - if (id != null) - { - mc = new SyntaxTree.method_call(); - mc.dereferencing_value = id; // дело в том, что это присваивание перенаправляет Parent на method_call, которого нет в синтаксическом дереве. - id.Parent = _procedure_call; // fix #891 вернули Parent назад - //DarkStar Add - //Добавил т.к. нужно для генерации отладочной инфы - mc.source_context = id.source_context; - } - else - { - SyntaxTree.addressed_value adrv = _procedure_call.func_name as SyntaxTree.addressed_value; - if (adrv != null) - { - mc = new SyntaxTree.method_call(); - mc.dereferencing_value = adrv; - adrv.Parent = _procedure_call; // fix #891 - //DarkStar Add - //Добавил т.к. нужно для генерации отладочной инфы - mc.source_context = adrv.source_context; - } - else - { - throw new CompilerInternalError("Undefined procedure name"); - } - } - } - //statement_node sn=convert_strong(_procedure_call.func_name); - statement_node sn = convert_strong(mc); - //проверяем на случай вызова типа real(a) ... - if (/*((sn is base_function_call) && (sn as base_function_call).IsExplicitConversion) - || (sn is SemanticTree.IReferenceNode) - || (sn is SemanticTree.IGetAddrNode) - || (sn is null_const_node) - || (sn is simple_array_indexing) - || (sn is basic_function_call) - || (sn is constant_node) - || (sn is class_field_reference)*/ - !(sn is base_function_call) && !(sn is exit_procedure) && !(sn is while_break_node) && !(sn is while_continue_node) - && !(sn is repeat_break_node) && !(sn is repeat_continue_node) && !(sn is for_break_node) && !(sn is for_continue_node) - && !(sn is foreach_break_node) && !(sn is foreach_continue_node) - ) - AddError(get_location(_procedure_call), "STATEMENT_EXPECTED"); - if (sn is base_function_call bfc && bfc.IsExplicitConversion) - AddError(get_location(_procedure_call), "STATEMENT_EXPECTED"); - - return_value(sn); - //_procedure_call.func_name.visit(this); - } - - public override void visit(SyntaxTree.variant_record_type _variant_record_type) - { - throw new NotSupportedError(get_location(_variant_record_type)); - } - - public override void visit(SyntaxTree.variant_types _variant_types) - { - throw new NotSupportedError(get_location(_variant_types)); - } - - public override void visit(SyntaxTree.variant_type _variant_type) - { - throw new NotSupportedError(get_location(_variant_type)); - } - - public override void visit(SyntaxTree.variant_list _variant_list) - { - throw new NotSupportedError(get_location(_variant_list)); - } - - public override void visit(SyntaxTree.variant _variant) - { - throw new NotSupportedError(get_location(_variant)); - } - - public override void visit(SyntaxTree.string_num_definition node) - { - location loc = get_location(node); - //if (SystemLibrary.SystemLibInitializer.ShortStringType.NotFound) - // throw new NotSupportedError(loc); - type_node tn = find_type(node.name.name, loc); - if (!(tn == SystemLibrary.SystemLibrary.string_type)) - AddError(new ExpectedType(SystemLibrary.SystemLibrary.string_type.name, loc)); - constant_node cn = convert_strong_to_constant_node(node.num_of_symbols, SystemLibrary.SystemLibrary.integer_type); - int length = (cn as int_const_node).constant_value; - if (length < 1 || length > 255) - AddError(loc, "TYPE_CAN_NOT_HAVE_THIS_SIZE_{0}", SystemLibrary.SystemLibrary.string_type.name); - return_value(context.create_short_string_type(length, loc)); - } - - public override void visit(SyntaxTree.literal_const_line _literal_const_line) - { - //DarkStar Add - string s = ""; - SyntaxTree.string_const strc; - SyntaxTree.sharp_char_const sharpcharconst; - SyntaxTree.char_const charconst; - SyntaxTree.syntax_tree_node tnf = _literal_const_line.literals[0], tnl = null; - for (int i = 0; i < _literal_const_line.literals.Count; i++) - { - if ((strc = _literal_const_line.literals[i] as SyntaxTree.string_const) != null) - s = s + strc.Value; - else - if ((sharpcharconst = _literal_const_line.literals[i] as SyntaxTree.sharp_char_const) != null) - s = s + Convert.ToChar(sharpcharconst.char_num); - else - if ((charconst = _literal_const_line.literals[i] as SyntaxTree.char_const) != null) - s = s + charconst.cconst; - if (i == _literal_const_line.literals.Count - 1) - tnl = _literal_const_line.literals[i]; - } - expression_node en = new string_const_node(s, new location(tnf.source_context.begin_position.line_num, tnf.source_context.begin_position.column_num, - tnl.source_context.end_position.line_num, tnl.source_context.end_position.column_num, current_document)); - return_value(en); - } - - public override void visit(SyntaxTree.sharp_char_const _sharp_char_const) - { - return_value(new char_const_node(Convert.ToChar(_sharp_char_const.char_num), get_location(_sharp_char_const))); - } - - public override void visit(SyntaxTree.raise_statement _raise_statement) - { - throw new NotSupportedError(get_location(_raise_statement)); - } - - public override void visit(SyntaxTree.char_const _char_const) - { - expression_node en = new char_const_node(_char_const.cconst, get_location(_char_const)); - return_value(en); - } - - private bool check_if_has_enum_consts(SyntaxTree.enum_type_definition _enum_type_definition) - { - bool has_val = false; - foreach (SyntaxTree.enumerator en in _enum_type_definition.enumerators.enumerators) - { - if (en.value != null) - { - has_val = true; - } - else - if (has_val) - AddError(get_location(en), "ALL_ENUM_CONSTANTS_NEEDED"); - } - return has_val; - } - - public override void visit(SyntaxTree.enum_type_definition _enum_type_definition) - { - //SSM 15/01/16 - реализация (integer,integer) - // Если кто-то - не named_type_reference с одним ident, то надо идти по ветке типов - это не м.б.перечисление - bool is_tuple_type = false; - foreach (SyntaxTree.enumerator en in _enum_type_definition.enumerators.enumerators) - { - if (!((en.name is named_type_reference) && (en.name as named_type_reference).names.Count()==1)) - { - is_tuple_type = true; - break; - } - } - - bool is_enum = false; - if (!is_tuple_type) // Значит, все - идентификаторы и сказать пока ничего нельзя - foreach (SyntaxTree.enumerator en in _enum_type_definition.enumerators.enumerators) - { - SyntaxTree.ident id = (en.name as named_type_reference).FirstIdent; - var si = context.CurrentScope.Find(id.name); - if ((si==null) || !(si.FirstOrDefault().sym_info is type_node)) - { - if (si != null && si.FirstOrDefault().sym_info is constant_definition_node) - { - constant_definition_node ncd = si.FirstOrDefault().sym_info as constant_definition_node; - if (_enum_type_definition.source_context != null && ncd.type.location != null && ncd.type.location.begin_line_num == _enum_type_definition.source_context.begin_position.line_num - && ncd.type.location.begin_column_num == _enum_type_definition.source_context.begin_position.column_num && ncd.type.location.doc.file_name == _enum_type_definition.source_context.FileName) - { - return_value(ncd.type); - return; - } - } - is_enum = true; - break; - } - - } - - if (!is_enum) // Значит, это определение типа - { - var lt = new List(); - for (var iii=0; iii<_enum_type_definition.enumerators.enumerators.Count(); iii++) - { - var en = _enum_type_definition.enumerators.enumerators[iii]; - var name = en.name; - if (en.value != null) - AddError(get_location(en.value), "TUPLE_TYPE_ERROR"); - lt.Add(name); - } - - if (lt.Count > 7) - AddError(get_location(_enum_type_definition), "TUPLE_TYPE_ELEMENTS_COUNT_MUST_BE_LESSEQUAL_7"); - - - var l = new List(); - l.Add(new ident("?System")); // System не должно быть найдено в пользовательском коде - l.Add(new ident("Tuple")); - - var tp = new template_param_list(lt); - // значит, это Tuple - создать его, обойти и выйти - var ttr = new SyntaxTree.template_type_reference(new named_type_reference(l), tp, _enum_type_definition.source_context); - visit(ttr); - return; - } - - //end SSM - - // Если мы здесь - значит, это перечислимый тип - - //throw new NotSupportedError(get_location(_enum_type_definition)); - //ivan added - int num = 0; - List cnsts = new List(); - check_if_has_enum_consts(_enum_type_definition); - foreach (SyntaxTree.enumerator en in _enum_type_definition.enumerators.enumerators) - { - SyntaxTree.ident id = (en.name as named_type_reference).FirstIdent; // это - точно идентификаторы - - constant_definition_node cdn = context.add_const_definition(id.name, get_location(id)); - if (en.value == null) - cdn.const_value = new enum_const_node(num++, null, get_location(id)); - else - { - constant_node cn = convert_strong_to_constant_node(en.value,SystemLibrary.SystemLibrary.integer_type); - check_for_strong_constant(cn,get_location(en.value)); - cdn.const_value = new enum_const_node((cn as int_const_node).constant_value,null,get_location(id)); - } - cnsts.Add(cdn); - } - common_type_node ctn = context.create_enum_type(null, get_location(_enum_type_definition)); //_enum_type_definition.values - num = 0; - foreach (SyntaxTree.enumerator en in _enum_type_definition.enumerators.enumerators) - { - SyntaxTree.ident id = (en.name as named_type_reference).FirstIdent; - constant_definition_node cdn = context.add_const_definition(id.name, get_location(id)); - if (en.value == null) - cdn.const_value = new enum_const_node(num++, null, get_location(id)); - else - { - constant_node cn = convert_strong_to_constant_node(en.value,SystemLibrary.SystemLibrary.integer_type); - check_for_strong_constant(cn,get_location(en.value)); - cdn.const_value = new enum_const_node((cn as int_const_node).constant_value,null,get_location(id)); - } - cdn.const_value.type = ctn; - } - foreach (constant_definition_node cdn in cnsts) - cdn.const_value.type = ctn; - internal_interface ii = SystemLibrary.SystemLibrary.integer_type.get_internal_interface(internal_interface_kind.ordinal_interface); - ordinal_type_interface oti_old = (ordinal_type_interface)ii; - enum_const_node lower_value = new enum_const_node(0, ctn, ctn.loc); - enum_const_node upper_value = new enum_const_node(ctn.const_defs.Count - 1, ctn, ctn.loc); - ordinal_type_interface oti_new = new ordinal_type_interface(oti_old.inc_method, oti_old.dec_method, - oti_old.inc_value_method, oti_old.dec_value_method, - oti_old.lower_eq_method, oti_old.greater_eq_method, oti_old.lower_method, oti_old.greater_method, lower_value, upper_value, oti_old.value_to_int, oti_old.ordinal_type_to_int); - - ctn.add_internal_interface(oti_new); - //foreach (constant_definition_node cdn in cnsts) - // cdn.const_value.type = ctn; - //context.leave_block(); - context.leave_record(); - return_value(ctn); - - } - - public override void visit(SyntaxTree.record_type _record_type) - { - } - - public override void visit(SyntaxTree.record_const node) - { - if (is_typed_const_def) - { - record_constant rc = new record_constant(node.rec_consts, get_location(node)); - rc.SetType(new RecordConstType(rc.location)); - return_value(rc); - } - else - { - record_initializer ri = new record_initializer(node.rec_consts, get_location(node)); - ri.type = new RecordConstType(ri.location); - return_value(ri); - } - } - - public override void visit(SyntaxTree.record_const_definition _record_const_definition) - { - throw new NotSupportedError(get_location(_record_const_definition)); - } - - public override void visit(SyntaxTree.set_type_definition _set_type_definition) - { - // throw new NotSupportedError(get_location(_set_type_definition)); - if (SystemLibrary.SystemLibInitializer.TypedSetType == null || SystemLibrary.SystemLibInitializer.CreateSetProcedure == null) - AddError(new NotSupportedError(get_location(_set_type_definition))); - type_node el_type = convert_strong(_set_type_definition.of_type); - if (el_type.IsPointer) - AddError(get_location(_set_type_definition.of_type), "POINTERS_IN_SETS_NOT_ALLOWED"); - //if (el_type == SystemLibrary.SystemLibrary.void_type) - // AddError(new VoidNotValid(get_location(_set_type_definition.of_type))); - check_for_type_allowed(el_type, get_location(_set_type_definition.of_type)); - check_using_static_class(el_type, get_location(_set_type_definition.of_type)); - return_value(context.create_set_type(el_type, get_location(_set_type_definition))); - } - - public override void visit(SyntaxTree.known_type_definition _known_type_definition) - { - throw new NotSupportedError(get_location(_known_type_definition)); - } - - public override void visit(SyntaxTree.default_indexer_property_node _default_indexer_property_node) - { - throw new NotSupportedError(get_location(_default_indexer_property_node)); - } - - public override void visit(SyntaxTree.class_definition _class_definition) - { - if (_class_definition.keyword == class_keyword.Record && _class_definition.Parent is var_def_statement) // безымянная запись - { - // SSM 27.02.12 - всё это перенес в синтаксический визитор UnnamedRecordsCheckVisitor - /*if (_class_definition.class_parents != null && _class_definition.class_parents.Count>0) - AddError(new SimpleSemanticError(get_location(_class_definition), "UNNAMED_RECORD_CANNOT_IMPLEMENT_INTERFACE")); - var pds = _class_definition.DescendantNodes().OfType(); - if (pds.Count() > 0) - AddError(new SimpleSemanticError(get_location(pds.First()), "UNNAMED_RECORD_CANNOT_CONTAIN_METHODS")); - - var sps = _class_definition.DescendantNodes().OfType(); - if (sps.Count() > 0) - AddError(new SimpleSemanticError(get_location(sps.First()), "UNNAMED_RECORD_CANNOT_CONTAIN_PROPERTIES")); - - var cds = _class_definition.DescendantNodes().OfType(); - if (cds.Count() > 0) - AddError(new SimpleSemanticError(get_location(cds.First()), "UNNAMED_RECORD_CANNOT_CONTAIN_CONSTRUCTORS")); - if (_class_definition.body.class_def_blocks.First().access_mod.access_level != access_modifer.public_modifer) - { - var f = _class_definition.body.class_def_blocks.First(); - var loc = get_location(f); - if (loc == null) - loc = get_location(_class_definition); - AddError(new SimpleSemanticError(loc, "UNNAMED_RECORD_CAN_CONTAIN_ONLY_ONE_PUBLIC_VISIBILITY_SECTION")); - } - - if (_class_definition.body.class_def_blocks.Count > 1) - { - var el1 = _class_definition.body.class_def_blocks.ElementAt(1); - var loc = get_location(el1.access_mod); - if (loc == null) - loc = get_location(_class_definition); - AddError(new SimpleSemanticError(loc, "UNNAMED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS")); - }*/ - - } - - if (_class_definition.attribute != class_attribute.None && _class_definition.body == null) - AddError(new SimpleSemanticError(get_location(_class_definition), "CLASS_ATTRIBUTE_NOT_ALLOWED_IN_CLASS_PREDEFINTIONS")); - if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Sealed) == SyntaxTree.class_attribute.Sealed) - { - context.converted_type.SetIsSealed(true); - if (_class_definition.keyword == SyntaxTree.class_keyword.Interface || _class_definition.keyword == SyntaxTree.class_keyword.TemplateInterface) - AddError(new SimpleSemanticError(get_location(_class_definition), "INTERFACE_CANNOT_BE_SEALED")); - } - if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Auto) == SyntaxTree.class_attribute.Auto) - { - if (_class_definition.keyword == SyntaxTree.class_keyword.Interface || _class_definition.keyword == SyntaxTree.class_keyword.TemplateInterface) - AddError(new SimpleSemanticError(get_location(_class_definition), "INTERFACE_CANNOT_BE_AUTO")); - } - if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Abstract) == SyntaxTree.class_attribute.Abstract && - (_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Sealed) == SyntaxTree.class_attribute.Sealed) - AddError(get_location(_class_definition), "ABSTRACT_CLASS_CANNOT_BE_SEALED"); - if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Abstract) == SyntaxTree.class_attribute.Abstract) - { - if (_class_definition.keyword != SyntaxTree.class_keyword.Class) - AddError(get_location(_class_definition), "ATTRIBUTE_{0}_NOT_ALLOWED", "abstract"); - context.converted_type.SetIsAbstract(true); - } - if ((_class_definition.attribute & class_attribute.Static) == class_attribute.Static) - { - if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Abstract) == SyntaxTree.class_attribute.Abstract) - AddError(get_location(_class_definition), "ATTRIBUTE_{0}_NOT_ALLOWED", "abstract"); - if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Sealed) == SyntaxTree.class_attribute.Sealed) - AddError(get_location(_class_definition), "ATTRIBUTE_{0}_NOT_ALLOWED", "sealed"); - if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Auto) == SyntaxTree.class_attribute.Auto) - AddError(get_location(_class_definition), "ATTRIBUTE_{0}_NOT_ALLOWED", "auto"); - if (_class_definition.keyword != SyntaxTree.class_keyword.Class) - AddError(get_location(_class_definition), "ONLY_CLASS_CAN_BE_STATIC"); - if (context.converted_type.is_generic_type_definition) - AddError(get_location(_class_definition), "STATIC_CLASS_CANNOT_BE_GENERIC"); - context.converted_type.SetIsStatic(true); - context.converted_type.SetIsSealed(true); - context.converted_type.SetIsAbstract(true); - } - switch (_class_definition.keyword) - { - case PascalABCCompiler.SyntaxTree.class_keyword.Class: - if (context.converted_type.is_value || context.converted_type.IsInterface) - { - AddError(get_location(_class_definition), "FORWARD_DECLARATION_OF_{0}_MISMATCH_DECLARATION", context.converted_type.name); - } - if ((_class_definition.class_parents != null) && (_class_definition.class_parents.types.Count > 0)) - { - if (context.converted_type.IsStatic) - AddError(get_location(_class_definition), "STATIC_CLASS_CANNOT_HAVE_PARENT"); - context.skip_check_where_sections = true; - type_node tn = ret.visit(_class_definition.class_parents.types[0]); - context.skip_check_where_sections = false; - //if (tn == context.converted_type) - if (type_table.original_types_equals(tn, context.converted_type)) - AddError(new UndefinedNameReference(tn.name, get_location(_class_definition.class_parents.types[0]))); - if (tn.IsSealed) - AddError(get_location(_class_definition.class_parents.types[0]), "PARENT_TYPE_IS_SEALED{0}", tn.name); - if (tn == SystemLibrary.SystemLibrary.value_type) - { - AddError(get_location(_class_definition.class_parents.types[0]), "CAN_NOT_INHERIT_FROM_VALUE_TYPE"); - } - if (tn.IsPointer) - { - AddError(get_location(_class_definition.class_parents.types[0]), "CAN_NOT_INHERIT_FROM_POINTER"); - } - if (tn.IsDelegate) - { - AddError(get_location(_class_definition.class_parents.types[0]), "CAN_NOT_INHERIT_FROM_FUNCTION_TYPE"); - } - if (tn == SystemLibrary.SystemLibrary.delegate_base_type || tn == SystemLibrary.SystemLibrary.system_delegate_type) - { - AddError(get_location(_class_definition.class_parents.types[0]), "CAN_NOT_INHERIT_FROM_DELEGATE_TYPE"); - } - Hashtable used_interfs = new Hashtable(); - //Если tn - это интерфейс - if (tn.IsInterface) - { - //Первым в списке предков идёт интерфейс, поэтому базовым будет object. - context.converted_type.SetBaseType(SemanticRules.ClassBaseType); - - //Добавляем интерфейс - used_interfs.Add(tn, tn); - type_table.AddInterface(context.converted_type, tn, get_location(_class_definition.class_parents.types[0])); - if (tn.is_generic_type_instance) - ret.visit(_class_definition.class_parents.types[0]); - } - else - { - if (convertion_data_and_alghoritms.ContainsForward(tn)) // SSM 20/05/2020 #2140 - { - AddError(get_location(_class_definition.class_parents.types[0]), "FORWARD_DECLARATION_{0}_AS_BASE_TYPE", tn.name); - } - if (tn.is_generic_parameter) - { - AddError(get_location(_class_definition.class_parents.types[0]), "CAN_NOT_INHERIT_FROM_GENERIC_PARAMETER"); - } - context.converted_type.SetBaseType(tn); - if (tn.is_generic_type_instance) - ret.visit(_class_definition.class_parents.types[0]); - var type_instances = generic_convertions.get_type_instances(context.converted_type); - if (type_instances != null) - foreach (generic_type_instance_info gti in type_instances) - { - gti.pseudo_instance.SetBaseType(tn); - } - } - //Теперь добавляем интерфейсы. - //Цикл с единицы, т.к. нулевой элемент уже был рассмотрен. - VisitAndAddInterfaces(context.converted_type, _class_definition.class_parents.types, 1, used_interfs); - //for (int i = 1; i < _class_definition.class_parents.types.Count; i++) - //{ - // type_node interf = ret.visit(_class_definition.class_parents.types[i]); - // AddInterface(context.converted_type, interf, get_location(_class_definition.class_parents.types[i])); - //} - } - else - { - if (!(context.converted_type.IsPartial && context.converted_type.base_type != null && context.converted_type.base_type != SemanticRules.ClassBaseType)) - context.converted_type.SetBaseType(SemanticRules.ClassBaseType); - } - - context.converted_type.is_class = true; - if (_class_definition.body == null && - (_class_definition.class_parents == null || _class_definition.class_parents.types.Count == 0)) - { - if (context.converted_type.ForwardDeclarationOnly) - { - AddError(new NameRedefinition(context.converted_type.name, context.converted_type.Location, get_location(_class_definition))); - } - context.types_predefined.Add(context.converted_type); - context.converted_type.ForwardDeclarationOnly = true; - } - else - { - context.converted_type.ForwardDeclarationOnly = false; - if (_class_definition.body == null) - { - generate_inherit_constructors(); - if (!context.converted_type.has_default_constructor) - { - generate_default_constructor(); - } - } - List names = new List(); - List types = new List(); - if ((_class_definition.IsAutoClass())) - { - // Если снова возникнет ошибка с предками в автоклассах, то не раскомментировать эти строки, а подумать, как разрешить - //if (_class_definition.class_parents!=null) - // AddError(new AutoClassMustNotHaveParents(get_location(_class_definition))); - // добавление членов автоклассов. Не забыть сделать, что от автоклассов нельзя наследовать - // Это спорный вопрос. С другой стороны от автоклассов хочется наследовать - - var cp = _class_definition.class_parents; - if (cp != null) - foreach (var c in cp.types) - { - var ff = convert_strong(c); - if (!ff.IsInterface) - AddError(new AutoClassMustNotHaveParents(get_location(_class_definition))); - - } - - SyntaxTreeBuilder.AddMembersForAutoClass(_class_definition,ref names,ref types); - - //if (names.Select(s => s.name.ToLower()).Distinct().Count() != names.Count) - - // Отдельный цикл по синт поддереву для вылавливания events - foreach (var l in _class_definition.body.class_def_blocks) - { - foreach (var m in l.members) - { - var mm = m as var_def_statement; - if (mm != null && mm.is_event) - AddError(get_location(mm), "AUTO_CLASS_MUST_NOT_HAVE_EVENTS"); - } - } - - for (var i = 0; i < types.Count; i++) - { - type_node tn = convert_strong(types[i]); - if (tn.IsEnum && types[i] is enum_type_definition) - AddError(get_location(types[i]), "AUTO_CLASS_MUST_NOT_HAVE_UNNAMED_ENUMS"); - if (tn.IsPointer) - AddError(get_location(types[i]), "AUTO_CLASS_MUST_NOT_HAVE_POINTERS"); - } - if (_class_definition.body != null) - foreach (class_members cl_mem in _class_definition.body.class_def_blocks) - { - foreach (declaration decl in cl_mem.members) - { - if (decl is var_def_statement) - { - type_definition type = (decl as var_def_statement).vars_type; - SyntaxTree.array_type arr = type as SyntaxTree.array_type; - if (type is SyntaxTree.class_definition || (arr != null && arr.indexers != null && arr.indexers.indexers.Count > 0 && arr.indexers.indexers[0] != null)) - { - AddError(get_location(type), "STRUCT_TYPE_DEFINITION_IN_AUTO_CLASS"); - } - } - } - } - } - //if (!SemanticRules.OrderIndependedNames) - - weak_node_test_and_visit(_class_definition.body); - - - } - common_type_node converted_type = context.converted_type; - context.leave_block(); - if (converted_type.IsSealed && converted_type.IsAbstract && !converted_type.IsStatic) - AddError(get_location(_class_definition), "ABSTRACT_CLASS_CANNOT_BE_SEALED"); - return; - case PascalABCCompiler.SyntaxTree.class_keyword.Record: - common_type_node ctn; - if (_record_created) - { - _record_created = false; - ctn = context.converted_type; - } - else - { - ctn = context.create_record_type(get_location(_class_definition), record_type_name); - if (record_is_generic) - { - context.create_generic_indicator(ctn); - visit_generic_params(ctn, _class_definition.template_args.idents); - } - else - { - if (_class_definition.template_args != null && _class_definition.template_args.idents != null) - { - AddError(get_location(_class_definition.template_args), "GENERIC_TYPE_NOT_ALLOWED_HERE"); - } - } - visit_where_list(_class_definition.where_section); - } - - if (context.CurrentScope is SymbolTable.BlockScope) - { - AddError(get_location(_class_definition), "RECORD_CANNOT_BE_DECLARED_IN_BLOCK"); - ctn.internal_is_value = true; - context.leave_record(); - return_value(ctn); - return; - } - - //Добавляем интерфейсы - предки. - if (_class_definition.class_parents != null) - { - VisitAndAddInterfaces(context.converted_type, _class_definition.class_parents.types, 0, new Hashtable()); - //for (int i = 0; i < _class_definition.class_parents.types.Count; i++) - //{ - // type_node interf = ret.visit(_class_definition.class_parents.types[i]); - // AddInterface(context.converted_type, interf, get_location(_class_definition.class_parents.types[i])); - //} - } - CheckWaitedRefTypes(ctn); - record_type_name = null; - record_is_generic = false; - context.converted_type.internal_is_value = true; - - if (_class_definition.body == null && - (_class_definition.class_parents == null || _class_definition.class_parents.types.Count == 0)) - { - if (context.converted_type.ForwardDeclarationOnly) - { - AddError(new NameRedefinition(context.converted_type.name, context.converted_type.Location, get_location(_class_definition))); - } - context.types_predefined.Add(context.converted_type); - context.converted_type.ForwardDeclarationOnly = true; - } - else - { - - context.converted_type.ForwardDeclarationOnly = false; - weak_node_test_and_visit(_class_definition.body); - - - } - /*if (_class_definition.body != null) - hard_node_test_and_visit(_class_definition.body); - else - { - context.converted_type.ForwardDeclarationOnly = true; - }*/ - /*if (_class_definition.body != null) - foreach (SyntaxTree.var_def_statement var in (_class_definition.body.class_def_blocks[0].members)) - { - hard_node_test_and_visit(var); - }*/ - context.leave_record(); - return_value(ctn); - return; - //ssyy owns - case PascalABCCompiler.SyntaxTree.class_keyword.Interface: - if (context.converted_type.is_value || !context.converted_type.IsInterface) - { - AddError(get_location(_class_definition), "FORWARD_DECLARATION_OF_{0}_MISMATCH_DECLARATION", context.converted_type.name); - } - if (SemanticRules.GenerateNativeCode) - context.converted_type.SetBaseType(SemanticRules.ClassBaseType); - else - context.converted_type.SetBaseType(SystemLibrary.SystemLibrary.object_type); - context.converted_type.IsInterface = true; - context.converted_type.is_class = true; - //Добавляем интерфейсы - предки. - if (_class_definition.class_parents != null) - { - VisitAndAddInterfaces(context.converted_type, _class_definition.class_parents.types, 0, new Hashtable()); - //for (int i = 0; i < _class_definition.class_parents.types.Count; i++) - //{ - // type_node interf = ret.visit(_class_definition.class_parents.types[i]); - // AddInterface(context.converted_type, interf, get_location(_class_definition.class_parents.types[i])); - //} - } - - InitInterfaceScope(context.converted_type); - - //if (_class_definition.body == null) - //{ - //throw new NotSupportedError(get_location(_class_definition)); - // throw new InterfaceForwardDeclaration(get_location(_class_definition)); - //} - if (_class_definition.body == null && - (_class_definition.class_parents == null || _class_definition.class_parents.types.Count == 0)) - { - if (context.converted_type.ForwardDeclarationOnly) - { - AddError(new NameRedefinition(context.converted_type.name, context.converted_type.Location, get_location(_class_definition))); - } - context.types_predefined.Add(context.converted_type); - context.converted_type.ForwardDeclarationOnly = true; - } - else - { - context.converted_type.ForwardDeclarationOnly = false; - weak_node_test_and_visit(_class_definition.body); - } - //hard_node_test_and_visit(_class_definition.body); - context.leave_block(); - return; - //\ssyy owns - default: - throw new NotSupportedError(get_location(_class_definition)); - } - } - - private void VisitAndAddInterfaces(common_type_node t, List types, int start, Hashtable used_interfaces) - { - for (int i = start; i < types.Count; i++) - { - type_node interf = ret.visit(types[i]); - location loc = get_location(types[i]); - if (used_interfaces[interf] != null) - { - AddError(loc, "INTERFACE_{0}_ALREADY_ADDED_TO_IMPLEMENTING_LIST", interf.PrintableName); - } - used_interfaces.Add(interf, interf); - check_cycle_interface_inheritance(t, interf, new List()); - type_table.AddInterface(t, interf, loc); - } - } - - private void InitInterfaceScope(common_type_node ctn) - { - List interf_scopes = new List(ctn.ImplementingInterfaces.Count); - foreach (type_node tnode in ctn.ImplementingInterfaces) - { - interf_scopes.Add(tnode.Scope); - } - (ctn.Scope as SymbolTable.InterfaceScope).TopInterfaceScopeArray = - interf_scopes.ToArray(); - } - - private void visit_function_realizations(SyntaxTree.declarations _decls) - { - foreach (SyntaxTree.declaration sd in _decls.defs) - { - common_namespace_function_node cnfn = context.get_method_to_realize(sd) as common_namespace_function_node; - if (cnfn != null) - { - context.push_function(cnfn); - - if ((sd as SyntaxTree.procedure_definition).proc_body != null) - { - hard_node_test_and_visit((sd as SyntaxTree.procedure_definition).proc_body); - add_clip_for_set(context.top_function); - context.leave_block(); - } - } - } - } - - private void visit_class_member_realizations(SyntaxTree.class_body_list _class_body) - { - if (context.converted_type.internal_is_value) - { - context.add_equal_operator_if_need(); - context.add_notequal_operator_if_need(); - } - - foreach (SyntaxTree.class_members clmem in _class_body.class_def_blocks) - { - foreach (SyntaxTree.declaration sd in clmem.members) - { - common_method_node cmn = context.get_method_to_realize(sd) as common_method_node; - - if (cmn != null) - { - // frninja 20/05/16 - ставим флаг is_yield_helper - if (sd is SyntaxTree.procedure_definition) - { - cmn.is_yield_helper = (sd as SyntaxTree.procedure_definition).proc_header.is_yield_helper; - } - // end frninja - - context.push_function(cmn); - if (!cmn.IsStatic) - { - type_node self_type = cmn.cont_type; - if (cmn.cont_type.is_generic_type_definition) - self_type = cmn.cont_type.get_instance(cmn.cont_type.generic_params.ConvertAll(o => (type_node)o));// new generic_instance_type_node(self_type, self_type.generic_params.ConvertAll(o => (type_node)o), self_type.base_type, self_type.name, self_type.type_access_level, self_type.comprehensive_namespace, self_type.loc); - if (!(cmn.is_constructor && cmn.cont_type.name.StartsWith("<>local_variables_class"))) - { - local_variable lv = new local_variable(compiler_string_consts.self_word, self_type, cmn, null); - cmn.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv)); - cmn.self_variable = lv; - } - else - { - local_variable lv = new local_variable(compiler_string_consts.self_word+"$", self_type, cmn, null); - cmn.scope.AddSymbol(compiler_string_consts.self_word+"$", new SymbolInfo(lv)); - cmn.self_variable = lv; - } - } - if ((sd as SyntaxTree.procedure_definition).proc_body != null) - { - hard_node_test_and_visit((sd as SyntaxTree.procedure_definition).proc_body); - add_clip_for_set(context.top_function); - context.leave_block(); - } - } - } - } - context.clear_member_bindings(); - } - - public override void visit(SyntaxTree.class_body_list _class_body) - { - foreach (SyntaxTree.class_members clmem in _class_body.class_def_blocks) - { - //hard_node_test_and_visit(clmem); - weak_node_test_and_visit(clmem); - } - if (SemanticRules.OrderIndependedMethodNames) - { - if (!context.converted_type.is_value && !context.converted_type.IsInterface) - { - generate_inherit_constructors(); - } - if (!context.converted_type.IsInterface && !context.converted_type.has_default_constructor) - { - generate_default_constructor(); - } - if (!context.namespace_converted || context.converted_type.name.IndexOf("<>") != -1) - visit_class_member_realizations(_class_body); - } - - if (!SemanticRules.OrderIndependedMethodNames) - { - if (!context.converted_type.is_value && !context.converted_type.IsInterface) - { - generate_inherit_constructors(); - } - if (!context.converted_type.IsInterface && !context.converted_type.has_default_constructor) - { - generate_default_constructor(); - } - } - - } - - private bool disable_order_independ; - - - //ssyy - public void generate_default_constructor() - { - if (context.converted_type.IsStatic) - return; - if (!context.converted_type.is_value) - { - if (!generic_convertions.type_has_default_ctor(context.converted_type.base_type, true)) - { - //У предка нет конструктора по умолчанию, - //невозможно сгенерировать конструктор по умолчанию. - AddError(context.converted_type.loc, "NO_DEFAULT_CONSTRUCTOR_INT_TYPE_{0}", context.converted_type.base_type.name); - return; - } - } - - SyntaxTree.class_members clmem = new SyntaxTree.class_members(); - if (context.converted_type.has_user_defined_constructor) - { - clmem.access_mod = new SyntaxTree.access_modifer_node(SyntaxTree.access_modifer.protected_modifer); - } - else - { - clmem.access_mod = new SyntaxTree.access_modifer_node(SyntaxTree.access_modifer.public_modifer); - } - SyntaxTree.procedure_attributes_list pal = new PascalABCCompiler.SyntaxTree.procedure_attributes_list(); - //pal.proc_attributes.Add(new PascalABCCompiler.SyntaxTree.procedure_attribute(SyntaxTree.proc_attribute.attr_overload)); attr_overload - убрал отовсюду! ССМ - SyntaxTree.constructor constr = new PascalABCCompiler.SyntaxTree.constructor(); - constr.name = new SyntaxTree.method_name(null, null, new PascalABCCompiler.SyntaxTree.ident(compiler_string_consts.default_constructor_name), null); - constr.proc_attributes = pal; - SyntaxTree.block bl = new SyntaxTree.block(); - bl.program_code = new SyntaxTree.statement_list(); - bl.program_code.left_logical_bracket = new SyntaxTree.token_info("begin"); - bl.program_code.right_logical_bracket = new SyntaxTree.token_info("end"); - clmem.members.Add(new SyntaxTree.procedure_definition(constr, bl)); - disable_order_independ = true; - clmem.visit(this); - disable_order_independ = false; - } - //\ssyy - - public override void visit(SyntaxTree.access_modifer_node _access_modifer_node) - { - //ssyy - if (context.converted_type != null && context.converted_type.IsInterface) - { - if (_access_modifer_node.access_level == SyntaxTree.access_modifer.none) - { - context.set_field_access_level(SemanticTree.field_access_level.fal_public); - } - else - { - AddError(get_location(_access_modifer_node), "ACCESS_MODIFER_IN_INTERFACE"); - } - return; - } - //\ssyy - switch (_access_modifer_node.access_level) - { - case SyntaxTree.access_modifer.private_modifer: - { - context.set_field_access_level(SemanticTree.field_access_level.fal_private); - break; - } - case SyntaxTree.access_modifer.protected_modifer: - { - context.set_field_access_level(SemanticTree.field_access_level.fal_protected); - break; - } - case SyntaxTree.access_modifer.public_modifer: - { - context.set_field_access_level(SemanticTree.field_access_level.fal_public); - break; - } - case SyntaxTree.access_modifer.internal_modifer: - { - context.set_field_access_level(SemanticTree.field_access_level.fal_internal); - break; - } - } - } - - public override void visit(SyntaxTree.class_members _class_members) - { - foreach (var def in _class_members.members.Where(d => d is const_definition || - d is consts_definitions_list || - d is variable_definitions || - d is var_def_statement)) - { - var lambdaSearcher = new LambdaSearcher(def); - if (lambdaSearcher.CheckIfContainsLambdas()) - { - AddError(new LambdasNotAllowedInFieldsInitialization(get_location(lambdaSearcher.FoundLambda))); - } - } - - weak_node_test_and_visit(_class_members.access_mod); - foreach (SyntaxTree.declaration sd in _class_members.members) - { - hard_node_test_and_visit(sd); - } - } - - public override void visit(SyntaxTree.index_property _index_property) - { - throw new NotSupportedError(get_location(_index_property)); - } - - public override void visit(SyntaxTree.simple_property _simple_property) - { - if (_simple_property.accessors == null) - AddError(get_location(_simple_property), "PROPERTYACCESSOR_{0}_OR_{1}_EXPECTED", compiler_string_consts.PascalReadAccessorName, compiler_string_consts.PascalWriteAccessorName); - if (_simple_property.property_type == null) - AddError(get_location(_simple_property.property_name), "TYPE_NAME_EXPECTED"); - - common_property_node pn = context.add_property(_simple_property.property_name.name, - get_location(_simple_property.property_name)); - assign_doc_info(pn, _simple_property); - //pn.polymorphic_state=SemanticTree.polymorphic_state.ps_common; - //pn.loc=get_location(_simple_property.property_name); - if (context.converted_type.IsStatic && _simple_property.attr != SyntaxTree.definition_attribute.Static) - AddError(get_location(_simple_property), "STATIC_CLASSES_CANNOT_NON_STATIC_MEMBERS"); - if (_simple_property.attr == SyntaxTree.definition_attribute.Static) - { - if (context.converted_type.IsInterface) - AddError(get_location(_simple_property), "INTERFACE_PROPERTIES_CANNOT_BE_STATIC"); - pn.polymorphic_state = SemanticTree.polymorphic_state.ps_static; - } - - if (_simple_property.virt_over_none_attr == proc_attribute.attr_virtual || _simple_property.virt_over_none_attr == proc_attribute.attr_override) - pn.polymorphic_state = SemanticTree.polymorphic_state.ps_virtual; - else if (_simple_property.virt_over_none_attr == proc_attribute.attr_abstract) - { - if (context.converted_type.IsInterface) - AddError(get_location(_simple_property), "ATTRIBUTE_{0}_NOT_ALLOWED", "abstract"); - context.converted_type.SetIsAbstract(true); - pn.polymorphic_state = SemanticTree.polymorphic_state.ps_virtual_abstract; - } - if (context.converted_type.is_value_type) - { - if (_simple_property.virt_over_none_attr == proc_attribute.attr_virtual) - AddError(get_location(_simple_property), "ATTRIBUTE_{0}_NOT_ALLOWED", "virtual"); - else if (_simple_property.virt_over_none_attr == proc_attribute.attr_override) - AddError(get_location(_simple_property), "ATTRIBUTE_{0}_NOT_ALLOWED", "override"); - else if (_simple_property.virt_over_none_attr == proc_attribute.attr_reintroduce) - AddError(get_location(_simple_property), "ATTRIBUTE_{0}_NOT_ALLOWED", "reintroduce"); - else if (_simple_property.virt_over_none_attr == proc_attribute.attr_abstract) - AddError(get_location(_simple_property), "ATTRIBUTE_{0}_NOT_ALLOWED", "abstract"); - } - parameter_list pal_big = new parameter_list(); - //TODO: Спросить у Саши как получить тип параметра - var,const и т.д. - if (_simple_property.parameter_list != null) - { - foreach (SyntaxTree.property_parameter pp in _simple_property.parameter_list.parameters) - { - parameter_list pal_small = new parameter_list(); - foreach (SyntaxTree.ident id in pp.names.idents) - { - common_parameter cp = new common_parameter(id.name, SemanticTree.parameter_type.value, null, - concrete_parameter_type.cpt_none, get_location(id)); - pal_small.AddElement(cp); - } - type_node tn = convert_strong(pp.type); - foreach (parameter pr in pal_small) - { - pr.type = tn; - } - pal_big.AddRange(pal_small); - } - } - pn.parameters.AddRange(pal_big); - pn.internal_property_type = convert_strong(_simple_property.property_type); - - if (_simple_property.accessors != null) - { - - convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors); - - List sil = null; - //definition_node dn = null; - - if (_simple_property.accessors.read_accessor != null) - { - convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.read_accessor); - if (_simple_property.accessors.read_accessor.accessor_name == null) - { - if (!context.converted_type.IsInterface && _simple_property.virt_over_none_attr != proc_attribute.attr_abstract) - { - AddError(get_location(_simple_property.accessors.read_accessor), "ACCESSOR_NAME_EXPECTED"); - } - pn.internal_get_function = GenerateGetSetMethodForInterfaceProperty(pn, get_location(_simple_property.accessors.read_accessor), true); - } - else - { - if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) - AddError(get_location(_simple_property.accessors.read_accessor), "ABSTRACT_PROPERTIES_CANNOT_HAVE_IMPLEMENTATION"); - convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.read_accessor.accessor_name); - sil = context.converted_type.find_in_type(_simple_property.accessors.read_accessor.accessor_name.name, context.CurrentScope); - - location loc1 = get_location(_simple_property.accessors.read_accessor.accessor_name); - - if (sil == null) - { - //AddError(new UndefinedNameReference(_simple_property.accessors.read_accessor.accessor_name.name, loc1)); - AddError(loc1, "NAME_IN_PROPERTY_READ_SECTION_MUST_BE_FIELD_OR_METHOD_NAME"); - } - - /*if (sil.FirstOrDefault().scope != context.CurrentScope) // SSM 22/05/20 - { - AddError(loc1, "NAME_IN_PROPERTY_READ_SECTION_MUST_BE_FIELD_OR_METHOD_NAME"); - }*/ - - //dn = check_name_node_type(_simple_property.accessors.read_accessor.accessor_name.name, - // si, loc1, general_node_type.function_node, general_node_type.variable_node); - - function_node read_accessor = sil.FirstOrDefault().sym_info as function_node; - - if (read_accessor != null) - { - if (!(read_accessor as common_method_node).IsStatic && _simple_property.attr == definition_attribute.Static) - AddError(loc1,"STATIC_PROPERTY_MUST_HAVE_STATIC_ACCESSOR"); - - bool good_func = true; - bool one_func = sil.Count() == 1; - int si_index = 0; - while(si_index < sil.Count()) - { - good_func = true; - if (read_accessor.parameters.Count != pn.parameters.Count) - { - good_func = false; - if (one_func) - { - AddError(new PropertyAndReadAccessorParamsCountConvergence(read_accessor, pn, loc1)); - } - } - //TODO: Сверять типы параметров - var, const и т.д. - else - { - for (int i1 = 0; good_func && i1 < read_accessor.parameters.Count; i1++) - { - if (read_accessor.parameters[i1].parameter_type != pn.parameters[i1].parameter_type || - read_accessor.parameters[i1].type != pn.parameters[i1].type) - { - good_func = false; - if (one_func) - { - AddError(loc1, "PROPERTY_{0}_AND_READ_ACCESSOR_{1}_PARAMS_TYPE_CONVERGENCE", pn.name, read_accessor.name); - } - } - } - if (read_accessor.return_value_type == null) - { - good_func = false; - if (one_func) - { - AddError(loc1, "PROPERTY_READ_ACCESSOR_CAN_NOT_BE_PROCEDURE"); - } - } - if (read_accessor.return_value_type != pn.property_type) - { - good_func = false; - if (one_func) - { - AddError(loc1, "PROPERTY_{0}_AND_READ_ACCESSOR_{1}_RETURN_VALUE_TYPE_CONVERGENCE", pn.name, read_accessor.name); - } - } - if (read_accessor is common_method_node && (read_accessor as common_method_node).is_constructor) - { - AddError(loc1, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); - } - } - if (good_func) - { - break; - } - ++si_index; - if (si_index < sil.Count()) - { - read_accessor = sil[si_index].sym_info as function_node; - } - } - if (!good_func) - { - AddError(loc1, "NO_OVERLOAD_FUNCTION_{0}_USEFUL_FOR_ACCESSOR", read_accessor.name); - } - read_accessor = GenerateGetMethod(pn, read_accessor as common_method_node, pn.loc); - - } - else - { - class_field cfield = sil.FirstOrDefault().sym_info as class_field; - if (cfield == null) - { - AddError(loc1, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); - } - if (_simple_property.parameter_list != null) - { - AddError(loc1, "INDEX_PROPERTY_ACCESSOR_CAN_NOT_BE_VARIABLE"); - } - if (cfield.type != pn.internal_property_type) - { - AddError(loc1, "PROPERTY_TYPE_MISMATCH_ACCESSOR_FIELD_TYPE"); - } - if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", cfield.name); - if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", cfield.name); - read_accessor = GenerateGetMethodForField(pn, compiler_string_consts.GetGetAccessorName(pn.name), cfield, loc1); - } - - //Вот здесь уже можем добавить акцессор для чтения. - pn.internal_get_function = read_accessor; - } - if (pn.internal_get_function != null && pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && pn.internal_get_function.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", pn.internal_get_function.name); - if (pn.internal_get_function != null && pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && pn.internal_get_function.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", pn.internal_get_function.name); - } - - if (_simple_property.accessors.write_accessor != null) - { - convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.write_accessor); - if (_simple_property.accessors.write_accessor.accessor_name == null) - { - if (!context.converted_type.IsInterface && _simple_property.virt_over_none_attr != proc_attribute.attr_abstract) - { - AddError(get_location(_simple_property.accessors.write_accessor), "ACCESSOR_NAME_EXPECTED"); - } - pn.internal_set_function = GenerateGetSetMethodForInterfaceProperty(pn, get_location(_simple_property.accessors.write_accessor), false); - } - else - { - if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) - AddError(get_location(_simple_property.accessors.write_accessor), "ABSTRACT_PROPERTIES_CANNOT_HAVE_IMPLEMENTATION"); - convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.write_accessor.accessor_name); - sil = context.converted_type.find_in_type(_simple_property.accessors.write_accessor.accessor_name.name, context.CurrentScope); - - location loc2 = get_location(_simple_property.accessors.write_accessor.accessor_name); - - if (sil == null) - { - //AddError( new UndefinedNameReference(_simple_property.accessors.write_accessor.accessor_name.name, loc2)); - AddError(loc2, "NAME_IN_PROPERTY_WRITE_SECTION_MUST_BE_FIELD_OR_METHOD_NAME"); - } - - /*if (sil.FirstOrDefault().scope != context.CurrentScope) // SSM 22/05/20 - { - AddError(loc2, "NAME_IN_PROPERTY_WRITE_SECTION_MUST_BE_FIELD_OR_METHOD_NAME"); - }*/ - - //dn = check_name_node_type(_simple_property.accessors.write_accessor.accessor_name.name, - // si, loc2, general_node_type.function_node, general_node_type.variable_node); - - function_node write_accessor = sil.FirstOrDefault().sym_info as function_node; - - if (write_accessor != null) - { - if (!(write_accessor as common_method_node).IsStatic && _simple_property.attr == definition_attribute.Static) - AddError(loc2, "STATIC_PROPERTY_MUST_HAVE_STATIC_ACCESSOR"); - - bool good_func = true; - bool one_func = sil.Count() == 1; - int si_index = 0; - while (si_index < sil.Count()) - { - good_func = true; - if (write_accessor.parameters.Count != pn.parameters.Count + 1) - { - good_func = false; - if (one_func) - { - AddError( new PropertyAndWriteAccessorParamsCountConvergence(write_accessor, pn, loc2)); - } - } - else - { - //TODO: Сверять типы параметров - var, const и т.д. - for (int i2 = 0; good_func && i2 < pn.parameters.Count; i2++) - { - if (write_accessor.parameters[i2].parameter_type != pn.parameters[i2].parameter_type || - write_accessor.parameters[i2].type != pn.parameters[i2].type) - { - good_func = false; - if (one_func) - { - AddError(loc2, "PROPERTY_{0}_AND_WRITE_ACCESSOR_{1}_PARAMS_TYPE_CONVERGENCE", pn.name ,write_accessor.name); - } - } - } - if (write_accessor.parameters[write_accessor.parameters.Count - 1].type != pn.property_type || - write_accessor.parameters[write_accessor.parameters.Count - 1].parameter_type != PascalABCCompiler.SemanticTree.parameter_type.value) - { - good_func = false; - if (one_func) - { - AddError(loc2, "PROPERTY_{0}_AND_WRITE_ACCESSOR_LAST_PARAMETER_TYPE_CONVERGENCE", pn.name); - } - } - if (write_accessor.return_value_type != null) - { - good_func = false; - if (one_func) - { - AddError(loc2, "PROPERTY_WRITE_ACCESSOR_CAN_NOT_BE_FUNCTION"); - } - } - } - if (good_func) - { - break; - } - ++si_index; - if (si_index < sil.Count()) - { - write_accessor = sil[si_index].sym_info as function_node; - } - } - if (!good_func) - { - AddError(loc2, "NO_OVERLOAD_FUNCTION_{0}_USEFUL_FOR_ACCESSOR", write_accessor.name); - } - if (write_accessor is common_method_node && (write_accessor as common_method_node).is_constructor) - { - AddError(loc2, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); - } - write_accessor = GenerateSetMethod(pn, write_accessor as common_method_node, pn.loc); - } - else - { - class_field cfield = sil.FirstOrDefault().sym_info as class_field; - if (cfield == null) - { - AddError(loc2, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); - } - - if (_simple_property.parameter_list != null) - { - AddError(loc2, "INDEX_PROPERTY_ACCESSOR_CAN_NOT_BE_VARIABLE"); - } - if (cfield.type != pn.internal_property_type) - { - AddError(loc2, "PROPERTY_TYPE_MISMATCH_ACCESSOR_FIELD_TYPE"); - } - if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", cfield.name); - if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", cfield.name); - write_accessor = GenerateSetMethodForField(pn, compiler_string_consts.GetSetAccessorName(pn.name), cfield, loc2); - } - //Вот здесь уже можем добавить акцессор для чтения. - pn.internal_set_function = write_accessor; - } - if (pn.internal_set_function != null && pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && pn.internal_set_function.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", pn.internal_set_function.name); - if (pn.internal_set_function != null && pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && pn.internal_set_function.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", pn.internal_set_function.name); - } - } - make_attributes_for_declaration(_simple_property,pn); - if (_simple_property.virt_over_none_attr == proc_attribute.attr_override) - context.set_override(pn); - //TODO: Можно сделать множество свойств по умолчанию. - if (_simple_property.array_default != null) - { - if (pn.parameters.Count == 0) - { - AddError(pn.loc, "DEFAULT_PROPERTY_MUST_BE_INDEXED"); - } - if (context.converted_type.default_property_node != null) - { - AddError(pn.loc, "DUPLICATE_DEFAULT_PROPERTY_IN_CLASS"); - } - context.converted_type.default_property = pn; - } - } - - private function_node GenerateGetMethod(common_property_node cpn, common_method_node accessor, location loc) - { - common_method_node cmn = new common_method_node( - "get_"+cpn.name, loc, cpn.common_comprehensive_type, - cpn.polymorphic_state, cpn.field_access_level, null); - cpn.common_comprehensive_type.methods.AddElement(cmn); - cmn.return_value_type = cpn.property_type; - cmn.is_overload = true; - foreach (common_parameter cp in accessor.parameters) - { - common_parameter new_cp = new common_parameter(cp.name, cp.type, cp.parameter_type, cp.common_function, cp.concrete_parameter_type, cp.default_value, loc); - cmn.parameters.AddElement(new_cp); - } - expression_node meth_call; - if (cpn.polymorphic_state == SemanticTree.polymorphic_state.ps_common || cpn.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual) - { - meth_call = new common_method_call(accessor, new this_node(cpn.common_comprehensive_type, loc), loc); - foreach (common_parameter cp in cmn.parameters) - { - (meth_call as common_method_call).parameters.AddElement(new common_parameter_reference(cp, 0, loc)); - } - } - else - { - meth_call = new common_static_method_call(accessor, loc); - foreach (common_parameter cp in cmn.parameters) - { - (meth_call as common_static_method_call).parameters.AddElement(new common_parameter_reference(cp, 0, loc)); - } - } - cmn.function_code = new return_node(meth_call, loc); - cpn.common_comprehensive_type.scope.AddSymbol("get_" + cpn.name, new SymbolInfo(cmn)); - return cmn; - } - - private function_node GenerateSetMethod(common_property_node cpn, common_method_node accessor, location loc) - { - common_method_node cmn = new common_method_node( - "set_" + cpn.name, loc, cpn.common_comprehensive_type, - cpn.polymorphic_state, cpn.field_access_level, null); - cpn.common_comprehensive_type.methods.AddElement(cmn); - //cmn.return_value_type = cpn.property_type; - cmn.is_overload = true; - foreach (common_parameter cp in accessor.parameters) - { - common_parameter new_cp = new common_parameter(cp.name, cp.type, cp.parameter_type, cp.common_function, cp.concrete_parameter_type, cp.default_value, loc); - cmn.parameters.AddElement(new_cp); - } - expression_node meth_call; - if (cpn.polymorphic_state == SemanticTree.polymorphic_state.ps_common || cpn.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual) - { - meth_call = new common_method_call(accessor, new this_node(cpn.common_comprehensive_type, loc), loc); - foreach (common_parameter cp in cmn.parameters) - { - (meth_call as common_method_call).parameters.AddElement(new common_parameter_reference(cp, 0, loc)); - } - } - else - { - meth_call = new common_static_method_call(accessor, loc); - foreach (common_parameter cp in cmn.parameters) - { - (meth_call as common_static_method_call).parameters.AddElement(new common_parameter_reference(cp, 0, loc)); - } - } - cmn.function_code = meth_call; - cpn.common_comprehensive_type.scope.AddSymbol("set_" + cpn.name, new SymbolInfo(cmn)); - return cmn; - } - - internal function_node GenerateSetMethodForField(common_property_node cpn, string AcessorName, class_field cf, location loc) - { - List exist_sil = context.find_only_in_namespace(AcessorName); - if (exist_sil != null && exist_sil.FirstOrDefault().sym_info.general_node_type != general_node_type.function_node) - { - AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", AcessorName); - } - if (exist_sil != null) - { - foreach (SymbolInfo exist_si in exist_sil) - { - function_node ff = (function_node)(exist_si.sym_info); - if (ff.parameters.Count == 1 && ff.parameters[0].type == cf.type) - { - AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", AcessorName); - } - } - } - common_method_node cmn = new common_method_node( - AcessorName, loc, /*cf.cont_type,*/ cpn.comprehensive_type as common_type_node, - cf.polymorphic_state, context.get_field_access_level(), null); - cpn.common_comprehensive_type.methods.AddElement(cmn); - common_parameter cp = new common_parameter( - compiler_string_consts.value, cf.type, SemanticTree.parameter_type.value, - cmn, concrete_parameter_type.cpt_none, null, loc); - cmn.parameters.AddElement(cp); - cmn.is_overload = true; - common_parameter_reference cpr = new common_parameter_reference(cp, 0, loc); - expression_node var_ref; - if (cf.polymorphic_state == SemanticTree.polymorphic_state.ps_common) - { - var_ref = new class_field_reference(cf, new this_node(cf.type, loc), loc); - } - else - { - var_ref = new static_class_field_reference(cf, loc); - } - cmn.function_code = find_operator(compiler_string_consts.assign_name, var_ref, cpr, loc); - cf.cont_type.Scope.AddSymbol(AcessorName, new SymbolInfo(cmn)); - return cmn; - } - - internal expression_node make_assign_operator(addressed_expression left, expression_node right, location loc) - { - return find_operator(compiler_string_consts.assign_name, left, right, loc); - } - - internal function_node GenerateGetMethodForField(common_property_node cpn, string AcessorName, class_field cf, location loc) - { - List exist_sil = context.find_only_in_namespace(AcessorName); - if (exist_sil != null && exist_sil.FirstOrDefault().sym_info.general_node_type != general_node_type.function_node) - { - AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", AcessorName); - } - if (exist_sil != null) - { - foreach (SymbolInfo exist_si in exist_sil) - { - if (((function_node)(exist_si.sym_info)).parameters.Count == 0) - { - AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", AcessorName); - } - } - } - common_method_node cmn = new common_method_node( - AcessorName, loc, /*cf.cont_type,*/ cpn.comprehensive_type as common_type_node, - cf.polymorphic_state, context.get_field_access_level(), null); - cpn.common_comprehensive_type.methods.AddElement(cmn); - cmn.return_value_type = cf.type; - cmn.is_overload = true; - expression_node var_ref; - if (cf.polymorphic_state == SemanticTree.polymorphic_state.ps_common) - { - var_ref = new class_field_reference(cf, new this_node(cf.type, loc), loc); - } - else - { - var_ref = new static_class_field_reference(cf, loc); - } - cmn.function_code = new return_node(var_ref, loc); - cf.cont_type.Scope.AddSymbol(AcessorName, new SymbolInfo(cmn)); // scope -> Scope SSM 23/05/20 - - return cmn; - } - - private function_node GenerateGetSetMethodForInterfaceProperty(common_property_node pn, location loc, bool get_meth) - { - - string AcessorName = (get_meth) ? - compiler_string_consts.GetGetAccessorName(pn.name) : - compiler_string_consts.GetSetAccessorName(pn.name); - List exist_sil = context.find_only_in_namespace(AcessorName); - if (exist_sil != null && exist_sil.FirstOrDefault().sym_info.general_node_type != general_node_type.function_node) - { - AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", AcessorName); - } - common_method_node cmn = new common_method_node( - AcessorName, loc, pn.common_comprehensive_type, - pn.polymorphic_state, context.get_field_access_level(), null); - cmn.is_overload = true; - foreach (common_parameter cp in pn.parameters) - { - common_parameter accp = new common_parameter(cp.name, cp.parameter_type, cmn, cp.concrete_parameter_type, cp.loc); - accp.type = cp.type; - accp.inital_value = cp.inital_value; - accp.intrenal_is_params = cp.intrenal_is_params; - accp.is_ret_value = cp.is_ret_value; - cmn.parameters.AddElement(accp); - } - if (get_meth) - { - cmn.return_value_type = pn.internal_property_type; - } - else - { - //foreach (common_parameter par in cmn.parameters) - //{ - // if (par.name == - //} - common_parameter accp = new common_parameter(compiler_string_consts.value_in_accessor_name, - SemanticTree.parameter_type.value, cmn, concrete_parameter_type.cpt_none, null); - accp.type = pn.internal_property_type; - cmn.parameters.AddElement(accp); - } - if (exist_sil != null) - { - foreach (SymbolInfo exist_si in exist_sil) - { - if (convertion_data_and_alghoritms.function_eq_params(cmn, (function_node)(exist_si.sym_info))) - { - AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", cmn.name); - } - } - } - pn.common_comprehensive_type.methods.AddElement(cmn); - pn.common_comprehensive_type.scope.AddSymbol(AcessorName, new SymbolInfo(cmn)); - return cmn; - } - - public override void visit(SyntaxTree.property_accessors _property_accessors) - { - throw new NotSupportedError(get_location(_property_accessors)); - } - - public override void visit(SyntaxTree.read_accessor_name _read_accessor_name) - { - throw new NotSupportedError(get_location(_read_accessor_name)); - } - - public override void visit(SyntaxTree.write_accessor_name _write_accessor_name) - { - throw new NotSupportedError(get_location(_write_accessor_name)); - } - - public override void visit(SyntaxTree.array_const _array_const) - { - if (_array_const.elements != null) - { - List elements = new List(); - List exprs = new List(); - foreach (SyntaxTree.expression expr in _array_const.elements.expressions) - { - if (is_typed_const_def) - elements.Add(convert_strong_to_constant_node(expr)); - else - exprs.Add(convert_strong(expr)); - } - if (is_typed_const_def) - { - array_const arrc = new array_const(elements, get_location(_array_const)); - arrc.SetType(new ArrayConstType(elements[0].type, elements.Count, arrc.location)); - return_value(arrc); - } - else - { - array_initializer arrc = new array_initializer(exprs, get_location(_array_const)); - arrc.type = new ArrayConstType(exprs[0].type, exprs.Count, arrc.location); - return_value(arrc); - } - } - else - { - //это пустой инициализатор записи - record_constant rc = new record_constant(new List(), get_location(_array_const)); - rc.SetType(new RecordConstType(get_location(_array_const))); - return_value(rc); - } - } - - private expressions_list get_set_initializer(expression_node cnfc) - { - return set_intls[cnfc]; - } - - private void add_set_initializer(expression_node cnfc, expressions_list exprs) - { - set_intls[cnfc] = exprs; - } - - private expression_node convert_diap_for_set(SyntaxTree.diapason_expr _diapason_expr, out type_node elem_type) - { - expression_node left = convert_strong(_diapason_expr.left); - if (left is typed_expression) left = convert_typed_expression_to_function_call(left as typed_expression); - expression_node right = convert_strong(_diapason_expr.right); - if (right is typed_expression) right = convert_typed_expression_to_function_call(right as typed_expression); - internal_interface ii = left.type.get_internal_interface(internal_interface_kind.ordinal_interface); - if (ii == null) - { - AddError(new OrdinalTypeExpected(left.location)); - } - internal_interface iir = right.type.get_internal_interface(internal_interface_kind.ordinal_interface); - if (iir == null) - { - AddError(new OrdinalTypeExpected(right.location)); - } - type_node_list tnl = new type_node_list(); - tnl.AddElement(left.type); - tnl.AddElement(right.type); - elem_type = convertion_data_and_alghoritms.select_base_type(tnl,true); - if (elem_type == SystemLibrary.SystemLibrary.object_type) - AddError(new SimpleSemanticError(get_location(_diapason_expr), "BAD_DIAPASON_IN_SET_TYPE")); - expression_node l = convertion_data_and_alghoritms.explicit_convert_type(left, PascalABCCompiler.SystemLibrary.SystemLibrary.integer_type); - expression_node r = convertion_data_and_alghoritms.explicit_convert_type(right, PascalABCCompiler.SystemLibrary.SystemLibrary.integer_type); - if (PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateDiapason.sym_info is common_namespace_function_node) - { - common_namespace_function_node cnfn = PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateDiapason.sym_info as common_namespace_function_node; - if (elem_type == PascalABCCompiler.SystemLibrary.SystemLibrary.char_type || elem_type == PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type || elem_type.IsEnum) - cnfn = PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateObjDiapason.sym_info as common_namespace_function_node; - common_namespace_function_call cnfc = new common_namespace_function_call(cnfn, get_location(_diapason_expr)); - if (elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.char_type && elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type && !elem_type.IsEnum) - { - cnfc.parameters.AddElement(l); - cnfc.parameters.AddElement(r); - } - else - { - cnfc.parameters.AddElement(left); - cnfc.parameters.AddElement(right); - } - return cnfc; - } - else - { - compiled_function_node cnfn = PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateDiapason.sym_info as compiled_function_node; - if (elem_type == PascalABCCompiler.SystemLibrary.SystemLibrary.char_type || elem_type == PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type || elem_type.IsEnum) - cnfn = PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateObjDiapason.sym_info as compiled_function_node; - compiled_static_method_call cnfc = new compiled_static_method_call(cnfn, get_location(_diapason_expr)); - if (elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.char_type && elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type && !elem_type.IsEnum) - { - cnfc.parameters.AddElement(l); - cnfc.parameters.AddElement(r); - } - else - { - cnfc.parameters.AddElement(left); - cnfc.parameters.AddElement(right); - } - return cnfc; - } - - } - - public override void visit(SyntaxTree.pascal_set_constant _pascal_set_constant) - { - //throw new NotSupportedError(get_location(_pascal_set_constant)); - if (SystemLibrary.SystemLibInitializer.TypedSetType == null || SystemLibrary.SystemLibInitializer.CreateSetProcedure == null) - AddError(new NotSupportedError(get_location(_pascal_set_constant))); - expressions_list consts = new expressions_list(); - type_node el_type = null; - type_node_list types = new type_node_list(); - if (_pascal_set_constant.values != null && _pascal_set_constant.values.expressions != null) - foreach (SyntaxTree.expression e in _pascal_set_constant.values.expressions) - { - if (e is SyntaxTree.nil_const) - ErrorsList.Add(new SimpleSemanticError(get_location(e), "NIL_IN_SET_CONSTRUCTOR_NOT_ALLOWED")); - else - if (e is SyntaxTree.diapason_expr) - { - expression_node en = convert_diap_for_set((e as SyntaxTree.diapason_expr), out el_type); - consts.AddElement(en); - if (el_type.IsPointer) - ErrorsList.Add(new SimpleSemanticError(get_location(e), "POINTERS_IN_SETS_NOT_ALLOWED")); - types.AddElement(el_type); - } - else - { - expression_node en = convert_strong(e); - if (en is typed_expression) en = convert_typed_expression_to_function_call(en as typed_expression); - if (en.type.type_special_kind == SemanticTree.type_special_kind.short_string) - en.type = SystemLibrary.SystemLibrary.string_type; - consts.AddElement(en); - types.AddElement(en.type); - } - } - type_node ctn = null; - if (consts.Count > 0) - { - el_type = convertion_data_and_alghoritms.select_base_type(types, true); - if (el_type == null) - AddError(new SimpleSemanticError(get_location(_pascal_set_constant), "IMPOSSIBLE_TO_INFER_SET_TYPE")); - - ctn = context.create_set_type(el_type, get_location(_pascal_set_constant)); - - } - else ctn = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node; - - /*if (el_type == SystemLibrary.SystemLibrary.string_type) - { - for (int i = 0; i < consts.Count; i++) - if (consts[i].type == SystemLibrary.SystemLibrary.char_type) - { - consts[i] = convertion_data_and_alghoritms.convert_type(consts[i], el_type); - } - } */ // Не работает ! SSM 19.03.19 - - expressions_list consts_copy = new expressions_list(); - consts_copy.AddRange(consts); - - function_node fn = convertion_data_and_alghoritms.select_function(consts, SystemLibrary.SystemLibInitializer.CreateSetProcedure.SymbolInfo, (SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info is common_namespace_function_node)?(SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node).loc:null); - - - if (fn is common_namespace_function_node) - { - common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, get_location(_pascal_set_constant)); - add_set_initializer(cnfc, consts_copy); - cnfc.ret_type = ctn; - for (int i = 0; i < consts.Count; i++) - cnfc.parameters.AddElement(consts[i]); - return_value(cnfc); - } - else - { - compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, get_location(_pascal_set_constant)); - add_set_initializer(cnfc, consts_copy); - cnfc.ret_type = ctn; - for (int i = 0; i < consts.Count; i++) - cnfc.parameters.AddElement(consts[i]); - return_value(cnfc); - } - //return_value(new common_namespace_function_call_as_constant(cnfc,cnfc.location)); - } - - public override void visit(SyntaxTree.array_const_new acn) - { - var lst = acn.elements.expressions.Select(ex => { var semex = convert_strong(ex); try_convert_typed_expression_to_function_call(ref semex); return semex; }).ToList(); - - type_node_list types = new type_node_list(); - foreach (var tn in lst.Select(ex => ex.type)) - types.AddElement(tn); - var el_type = convertion_data_and_alghoritms.select_base_type_for_arr_const_new(types, lst, true); - var syntax_type = new SyntaxTree.semantic_type_node(el_type); - //SyntaxTree.semantic_addr_value sav; - var plist = new SyntaxTree.expression_list(new int32_const(acn.elements.Count)); - var nn = new SyntaxTree.new_expr(syntax_type, plist, true, new SyntaxTree.array_const(acn.elements, acn.elements.source_context), acn.source_context); - visit(nn); - } - - - internal List get_function_instances(List sil, List type_pars, string name, location loc, bool stop_on_error) - { - List tparams = visit_type_list(type_pars); - for (int i = 0; i < tparams.Count; i++) - { - CompilationErrorWithLocation err = generic_parameter_eliminations.check_type_generic_useful(tparams[i], loc); - if (err != null) - { - AddError(err); - } - } - List start = null; - if (sil != null) - { - foreach (SymbolInfo si in sil) - { - function_node fn = si.sym_info as function_node; - if (fn != null) - { - function_node inst = fn.get_instance(tparams, stop_on_error, loc); - if (inst != null) - { - SymbolInfo s = new SymbolInfo(inst); - if (start == null) - { - start = new List { s }; - } - else - { - start.Add(s); - } - } - } - } - } - if (start == null) - { - AddError(loc, "NO_FUNCTIONS_{0}_CAN_BE_USED_WITH_THIS_SPECIFICATION", name); - } - return start; - } - - private List get_generic_functions(List funcs, bool stop_on_none, location loc) - { - List start = null; - if (funcs != null) { - foreach (SymbolInfo func in funcs) - { - function_node f = func.sym_info as function_node; - if (f.is_generic_function) - { - //Проверяем на совпадение - bool found = false; - if (start != null) - { - foreach (SymbolInfo fsi in start) - { - if (fsi == func) - break; - if (convertion_data_and_alghoritms.function_eq_params(fsi.sym_info as function_node, f)) - { - found = true; - break; - } - } - } - if (!found) - { - if (start == null) - { - start = new List { func }; - } - else - { - start.Add(func); - } - } - } - } - } - if (start == null) - { - if (stop_on_none) - { - AddError(loc, "TRIANGLE_BRACKETS_NOT_ALLOWED_WITH_COMMON_FUNCTIONS"); - } - return null; - } - return start; - } - - private void visit_mc_helper(motivation mot, expression_node expr_node, location loc, expressions_list exprs, string msg, bool check_loop_variable = false) - { - switch (mot) - { - case motivation.expression_evaluation: - { - // SSM 28/11/18 Проверка, что var-параметры не являются параметрами цикла for или foreach - if (check_loop_variable) - { - var fc = expr_node as base_function_call; - if (fc != null) // здесь обрезаются такие волшебные функции как exit, у которых базовый тип - expr_node. Для них var-параметры проверяются отдельно (это Inc, Dec, Read) - { - var fun = fc.function; - for (var i = 0; i < fun.parameters.Length; i++) - { - if (fun.parameters[i].parameter_type == SemanticTree.parameter_type.var) - { - check_on_loop_variable(exprs[i]); - } - } - } - } - - return_value(expr_node); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(expr_node); - return; - } - default: - { - AddError(loc, msg); - return; - } - } - } - - class SymInfoComparer: EqualityComparer - { - public override bool Equals(SymbolInfo x, SymbolInfo y) - { - return x.sym_info == y.sym_info; - } - public override int GetHashCode(SymbolInfo codeh) - { - return 0; - } - } - - internal void visit_method_call(SyntaxTree.method_call _method_call) - { - // frninja 01/03/16 - for iterator capturing (yield) - if (_method_call.dereferencing_value is yield_unknown_ident) - { - var nodeToVisit = new method_call(ProcessUnknownIdent(_method_call.dereferencing_value as yield_unknown_ident), _method_call.parameters); - visit(nodeToVisit); - return; - } - // end frninja - - //lroman - if (_method_call.dereferencing_value is closure_substituting_node) - { - var nodeToVisit = - new method_call(((closure_substituting_node)_method_call.dereferencing_value).substitution, - _method_call.parameters); - visit(nodeToVisit); - return; - } - - if (_method_call.dereferencing_value is dot_node dn && dn.right is operator_name_ident) - { - AddError(get_location(dn.right), "OPERATIONS_CANNOT_BE_CALLED_USING_THIS_SYNTAX"); - } - - bool proc_wait = procedure_wait; - bool lambdas_are_in_parameters = false; //lroman// - - var syntax_nodes_parameters = _method_call.parameters == null - ? new List() - : _method_call.parameters.expressions; - if (procedure_wait) - { - procedure_wait = false; - } - //throw new ArgumentNullException("test"); - - var mot = motivation_keeper.motivation; - motivation_keeper.reset(); - - expression_node expr_node = null; - expressions_list exprs = new expressions_list(); - - SyntaxTree.ident id = null; - - List sil = null; - - type_node to_type = null; - - SyntaxTree.addressed_value deref_value = _method_call.dereferencing_value; - int templ_args_count = 0; - //bool needs_generic_type_search = false; - SyntaxTree.ident_with_templateparams iwt = deref_value as SyntaxTree.ident_with_templateparams; - if (iwt != null) - { - deref_value = iwt.name; - templ_args_count = iwt.template_params.params_list.Count; - //needs_generic_type_search = _method_call.parameters.expressions.Count == 1; - } - - SyntaxTree.inherited_ident inh_id = deref_value as SyntaxTree.inherited_ident; - if (inh_id != null) - { - inherited_ident_processing = true; - sil = find_in_base(inh_id); - if (sil != null) - if (sil.FirstOrDefault().sym_info is common_method_node) - { - if ((sil.FirstOrDefault().sym_info as common_method_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) - AddError(get_location(inh_id), "CANNOT_CALL_ABSTRACT_METHOD"); - } - else - if (sil.FirstOrDefault().sym_info is compiled_function_node) - { - if ((sil.FirstOrDefault().sym_info as compiled_function_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) - AddError(get_location(inh_id), "CANNOT_CALL_ABSTRACT_METHOD"); - } - id = inh_id; - } - else - { - id = deref_value as SyntaxTree.ident; - if (id != null && id.name != null && id.name.IndexOf('.') != -1) - { - var arr = id.name.Split('.'); - deref_value = new dot_node(new ident(id.name.Substring(0, id.name.LastIndexOf('.')), id.source_context), new ident(arr[arr.Length-1],id.source_context)); - id = null; - } - if (id != null) - { - - if (templ_args_count != 0) - { - //Ищем generics - sil = context.find(id.name + compiler_string_consts.generic_params_infix + templ_args_count.ToString()); - if (sil != null) - { - sil = new List { new SymbolInfo(get_generic_instance(sil?.FirstOrDefault(), iwt.template_params.params_list)) }; - iwt = null; - } - } - if (sil == null) - { - SyntaxTree.operator_name_ident oni = id as SyntaxTree.operator_name_ident; - if (oni != null) - { - sil = context.find(name_reflector.get_name(oni.operator_type)); - } - else - { - sil = context.find(id.name); - if (templ_args_count != 0 && sil != null) - { - SymbolInfo conv = ConvertTypeToInstance(sil?.FirstOrDefault(), iwt.template_params.params_list, get_location(id)); - if (conv != null) - { - sil = new List { conv }; - iwt = null; - } - } - if (sil != null && id.name.ToLower() == "reset" && sil.FirstOrDefault().sym_info is common_method_node && (sil.FirstOrDefault().sym_info as common_method_node).cont_type.name.Contains("clyield#") && _method_call.ParametersCount > 0) - { - sil = context.converted_namespace.find(id.name); - } - if (sil != null && id.name.ToLower() == "create" && context.converted_type != null && sil.FirstOrDefault().sym_info is common_method_node && (sil.FirstOrDefault().sym_info as common_method_node).is_constructor) - { - List base_si_list = context.converted_type.base_type.find(id.name); - if (base_si_list != null) - sil.AddRange(base_si_list); - } - } - } - } - if (sil == null) - { - SyntaxTree.dot_node _dot_node = deref_value as SyntaxTree.dot_node; - if (_dot_node != null) - { - bool skip_first_parameter = false; //lroman// - bool has_extension_overload = false; - semantic_node sn = convert_semantic_strong(_dot_node.left); - - //SyntaxTree.ident id_right = ConvertOperatorNameToIdent(_dot_node.right as SyntaxTree.ident); - SyntaxTree.ident id_right = _dot_node.right as SyntaxTree.ident; - switch (sn.general_node_type) - { - case general_node_type.expression: - { - expression_node exp = (expression_node)sn; - if (exp is typed_expression) - try_convert_typed_expression_to_function_call(ref exp); - location subloc = get_location(id_right); - if (exp is typed_expression) - AddError(new UndefinedNameReference(id_right.name, subloc)); - SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; - if (oni_right != null) - { - sil = exp.type.find_in_type(name_reflector.get_name(oni_right.operator_type), context.CurrentScope); - } - else - { - sil = exp.type.find_in_type(id_right.name, context.CurrentScope); - sil = sil?.Distinct(new SymInfoComparer()).ToList(); // SSM 16/06/20 - удалил дубли для порядка - if (sil != null && sil.FirstOrDefault().sym_info != null && sil.FirstOrDefault().sym_info.semantic_node_type == semantic_node_type.wrap_def) - { - BasePCUReader.RestoreSymbols(sil, id_right.name); - } - } - - if (sil == null) - { - AddError(new UndefinedNameReference(id_right.name, subloc)); - } - - if (sil.FirstOrDefault().sym_info.general_node_type != general_node_type.function_node) - { - if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.type_node) - { - to_type = ((type_node)(sil.FirstOrDefault().sym_info)); - } - else - { - dot_node_as_expression_dot_ident(exp, id_right, motivation.expression_evaluation, _dot_node.left); - exp = ret.get_expression(); - internal_interface ii = exp.type.get_internal_interface(internal_interface_kind.delegate_interface); - if (ii == null) - { - AddError(subloc, "EXPECTED_DELEGATE"); - } - delegate_internal_interface dii = ii as delegate_internal_interface; - sil = new List { new SymbolInfo(dii.invoke_method) }; - } - } - - if (to_type != null) - { - if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1)) - { - AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED"); - } - } - List tmp_sil = sil; - if (sil != null) - { - foreach (SymbolInfo si in sil) - { - if (si.sym_info is common_namespace_function_node) - { - common_namespace_function_node cnfn = si.sym_info as common_namespace_function_node; - if (cnfn.ConnectedToType != null && !cnfn.IsOperator) - { - exprs.AddElementFirst(exp); - skip_first_parameter = true; - break; - } - } - if (si.sym_info is compiled_function_node) - { - compiled_function_node cfn = si.sym_info as compiled_function_node; - if (cfn.ConnectedToType != null) - { - exprs.AddElementFirst(exp); - skip_first_parameter = true; - if (cfn.is_generic_function) - { - //generic_convertions.DeduceFunction(cfn, exprs); - //si.sym_info = cfn.get_instance(new List(new type_node[] { exp.type }), true, get_location(_method_call)); - } - break; - } - - } - } - } - - if (skip_first_parameter) - { - List new_sil = new List(); - bool has_obj_methods = false; - if (sil != null) - { - foreach (SymbolInfo si in sil) - { - if (si.sym_info is common_namespace_function_node) - { - common_namespace_function_node cnfn = si.sym_info as common_namespace_function_node; - if (cnfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static || cnfn.ConnectedToType != null) - new_sil.Add(si); - if (cnfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cnfn.ConnectedToType == null) - has_obj_methods = true; - } - else if (si.sym_info is compiled_function_node) - { - compiled_function_node cfn = si.sym_info as compiled_function_node; - if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static || cfn.ConnectedToType != null) - new_sil.Add(si); - if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfn.ConnectedToType == null) - has_obj_methods = true; - } - else if (si.sym_info is common_method_node) - { - common_method_node cfn = si.sym_info as common_method_node; - if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - new_sil.Add(si); - if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - has_obj_methods = true; - } - } - } - if (new_sil.Count() != 0) - sil = new_sil; - else - sil = null; - } - if (_method_call.parameters != null) - { - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) - { - #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов - //lroman// - if (en is SyntaxTree.function_lambda_definition) - { - lambdas_are_in_parameters = true; - ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; - } - //lroman// - #endregion - var cen = convert_strong(en); - exprs.AddElement(cen); - } - } - - expression_node subexpr1 = null; - - if (to_type != null) - { - subexpr1 = convertion_data_and_alghoritms.explicit_convert_type(exprs[0], to_type); - } - else - { - if (iwt != null) - { - sil = get_generic_functions(sil, true, subloc); - sil = get_function_instances(sil, iwt.template_params.params_list, id_right.name, subloc, sil.Count() <= 1); - } - #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим - //lroman// - if (lambdas_are_in_parameters) - { - LambdaHelper.processingLambdaParametersForTypeInference++; - // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями - List spf = null; - try - { - ThrowCompilationError = false; - function_node ffn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters); - if (ffn == null) - { - if (skip_first_parameter) - { - expressions_list ex_list = new expressions_list(); - ex_list.AddRange(exprs); - ex_list.remove_at(0); - // Последний параметр - странный. Глупо искать не в методах расширения если это - метод расширения и мы удаляем затем первый параметр - ffn = convertion_data_and_alghoritms.select_function(ex_list, sil, subloc, syntax_nodes_parameters/*,true*/); - if (ffn == null) - { - ThrowCompilationError = true; - Errors.Error last_err = LastError(); - if (/*last_err is NoFunctionWithSameParametresNum && */ErrorsList.Count > 0) - throw LastError(); - else - throw last_err; - } - RemoveLastError(); - skip_first_parameter = false; - exprs = ex_list; - ThrowCompilationError = true; - } - else - { - ThrowCompilationError = true; - throw LastError(); - } - - } - ThrowCompilationError = true; - int exprCounter = 0; - if (skip_first_parameter) - { - exprCounter++; - } - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - exprCounter++; - continue; - } - else - { - var enLambda = (SyntaxTree.function_lambda_definition)en; - LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this); - enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; - exprs[exprCounter] = convert_strong(en); - enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; - exprCounter++; - } - } - } - catch (SeveralFunctionsCanBeCalled sf) - { - spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна - } - - Exception lastmultex = null; - if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try - { // exprs - глобальная, поэтому надо копировать - int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка - // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. - // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! - int GoodVersionsCount = 0; - int GoodVersionsCountWithSameResType = 0; - for (int i = 0; i < spf.Count; i++) // цикл по версиям - { - function_node fnn = spf[i]; - try - { - int exprCounter = 0; - if (skip_first_parameter) - { - exprCounter++; - } - - expressions_list exprs1 = new expressions_list(); - exprs1.AddRange(exprs); // сделали копию - - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - exprCounter++; - continue; - } - else - { - var fld = en as SyntaxTree.function_lambda_definition; - - var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо - var fl = fld.lambda_visit_mode; - - // запомнили типы параметров лямбды - SSM - object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы - for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) - { - var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; - if (laminftypeK == null) - realparamstype[k] = null; - else realparamstype[k] = laminftypeK.real_type; - } - - // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим - var restype = fld.return_type as SyntaxTree.lambda_inferred_type; - object realrestype = null; - if (restype != null) - realrestype = restype.real_type; - LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this); - fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman - fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! - - //contextChanger.SaveContextAndUpToNearestDefSect(); - try - { - exprs1[exprCounter] = convert_strong(en); - - type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; - type_node resformaltype = fld.RealSemTypeOfResult as type_node; - var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность - if (bbb) - { - GoodVersionsCountWithSameResType += 1; - spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. - } - - /*compiled_type_node tt; - tt = fnn.parameters[exprCounter].type as compiled_type_node; - if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) - { - resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func - тип возвращаемого значения - var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность - if (bbb) - { - GoodVersionsCountWithSameResType += 1; - spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. - } - }*/ - } - catch - { - throw; - } - finally - { - LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); - // восстанавливаем сохраненный тип возвращаемого значения - if (restype != null) - restype.real_type = realrestype; - // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно - for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) - { - var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; - if (laminftypeK != null) - laminftypeK.real_type = realparamstype[k]; - } - - fld.lambda_name = lambdaName; //lroman Восстанавливаем имена - fld.lambda_visit_mode = fl; - } - - //contextChanger.RestoreCurrentContext(); - exprCounter++; - } - } - /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так - { - spfnum = -2; - break; - }*/ - - if (GoodVersionsCountWithSameResType == 0) - spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения - GoodVersionsCount += 1; - for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо - exprs[j] = exprs1[j]; - } - catch (Exception e) - { - // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать - //contextChanger.RestoreCurrentContext(); - lastmultex = e; - } - } // конец цикла по версиям - if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения - throw new SeveralFunctionsCanBeCalled(subloc, spf); - if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд - { - throw lastmultex; - //throw new NoFunctionWithSameArguments(subloc2, false); - } - - int kk = 0; - if (skip_first_parameter) - kk++; - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - kk++; - continue; - } - else - { - LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); - exprs[kk] = convert_strong(en); - kk++; - } - } - } - // SSM 21.05.14 end - LambdaHelper.processingLambdaParametersForTypeInference--; - } - //lroman// - #endregion - - function_node fn = null; - if (!skip_first_parameter || sil.Count() == 1) - fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters); - else - { - try - { - ThrowCompilationError = false; - fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters); - if (fn == null && skip_first_parameter) - { - if (sil.Count() == 1) - { - ThrowCompilationError = true; - throw LastError(); - } - Errors.Error last_err = LastError(); - skip_first_parameter = false; - sil = tmp_sil; - exprs.remove_at(0); - fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters,true); - if (fn == null) - { - ThrowCompilationError = true; - RemoveLastError(); - if (last_err is CanNotConvertTypes) - { - var from_type = (last_err as CanNotConvertTypes).from; - foreach (SymbolInfo si in sil) - { - function_node si_fn = si.sym_info as function_node; - if (si_fn != null && si_fn.is_extension_method && si_fn.parameters[0].type == from_type) - { - throw new NoFunctionWithSameParametresNum(subloc, true, si_fn); - } - } - } - throw last_err; - } - } - else if (fn != null && skip_first_parameter && sil.Count() > 1 && !sil.HasOnlyExtensionMethods()) - { - function_node tmp_fn = fn; - exprs.remove_at(0); - sil = tmp_sil; - fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters,true); - if (fn == null) - { - fn = tmp_fn; - RemoveLastError(); - exprs.AddElementFirst(exp); - } - } - } - catch (Exception ex) - { - ThrowCompilationError = true; - if (skip_first_parameter) - { - sil = tmp_sil; - exprs.remove_at(0); - fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters,true); - } - else - throw ex; - } - ThrowCompilationError = true; - } - SemanticTree.IGenericInstance igi = fn as SemanticTree.IGenericInstance; - if (igi != null) - { - //проверяем на соответствие ограничителям - int num_err; - //CompilationErrorWithLocation err = generic_parameter_eliminations.check_type_list( - } - base_function_call bfc = create_not_static_method_call(fn, exp, get_location(id_right), proc_wait); - bfc.parameters.AddRange(exprs); - subexpr1 = bfc; - } - - visit_mc_helper(mot, subexpr1, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED",true); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(subexpr1); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(subexpr1); - return; - } - default: - { - AddError(subexpr1.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - }*/ - - } - case general_node_type.namespace_node: - { - namespace_node nsn = (namespace_node)sn; - if (templ_args_count != 0) - { - //Ищем generics - sil = context.find(id_right.name + compiler_string_consts.generic_params_infix + templ_args_count.ToString()); - if (sil != null) - { - sil = new List { new SymbolInfo(get_generic_instance(sil?.FirstOrDefault(), iwt.template_params.params_list)) }; - iwt = null; - } - } - if (sil == null) - { - SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; - if (oni_right != null) - { - sil = nsn.find(name_reflector.get_name(oni_right.operator_type)); - } - else - { - sil = nsn.findOnlyInNamespace(id_right.name); - if (templ_args_count != 0) - { - sil = nsn.find(id_right.name + compiler_string_consts.generic_params_infix + templ_args_count.ToString()); - if (sil != null) - { - sil = new List { new SymbolInfo(get_generic_instance(sil?.FirstOrDefault(), iwt.template_params.params_list)) }; - iwt = null; - } - /*SymbolInfo conv = ConvertTypeToInstance(sil?.FirstOrDefault(), iwt.template_params.params_list, get_location(id_right)); - if (conv != null) - { - sil = new List { conv }; - iwt = null; - }*/ - } - } - } - id = id_right; - break; - } - case general_node_type.unit_node: - { - unit_node un = (unit_node)sn; - SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; - if (oni_right != null) - { - sil = un.find_only_in_namespace(name_reflector.get_name(oni_right.operator_type)); - } - else - { - sil = un.find_only_in_namespace(id_right.name); - } - id = id_right; - break; - } - case general_node_type.type_node: - { - type_node tn = (type_node)sn; - - check_for_type_allowed(tn, get_location(id_right)); - SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; - if (oni_right != null) - { - sil = tn.find_in_type(name_reflector.get_name(oni_right.operator_type), context.CurrentScope); - } - else - { - sil = tn.find_in_type(id_right.name, context.CurrentScope);//CurrentScope - delete_inherited_constructors(ref sil, tn); - delete_extension_methods(ref sil, tn); // SSM 2.2.2016 Пока временно закомментировал - в старом коде этого не было. Из-за этого не работает System.Linq.Enumerable.Select - } - - //definition_node ddn2=check_name_node_type(id_right.name,si,get_location(id_right), - // general_node_type.function_node); - - expression_node exp = null; - location subloc = get_location(id_right); - - if (sil == null) - { - AddError(new UndefinedNameReference(id_right.name, subloc)); - } - - if (sil.FirstOrDefault().sym_info.general_node_type != general_node_type.function_node) - { - if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.type_node) - { - to_type = ((type_node)(sil.FirstOrDefault().sym_info)); - } - else - { - dot_node_as_type_ident(tn, id_right, motivation.expression_evaluation); - exp = ret.get_expression(); - internal_interface ii = exp.type.get_internal_interface(internal_interface_kind.delegate_interface); - if (ii == null) - { - AddError(subloc, "EXPECTED_DELEGATE"); - } - delegate_internal_interface dii = ii as delegate_internal_interface; - sil = new List { new SymbolInfo(dii.invoke_method) }; - } - } - - if (to_type != null) - { - if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1)) - { - AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED"); - } - } - - if (_method_call.parameters != null) - { - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) - { - #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов - //lroman// - if (en is SyntaxTree.function_lambda_definition) - { - lambdas_are_in_parameters = true; - ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; - } - //lroman// - #endregion - exprs.AddElement(convert_strong(en)); - } - } - - expression_node subexpr2 = null; - - if (to_type != null) - { - - subexpr2 = convertion_data_and_alghoritms.explicit_convert_type(exprs[0], to_type); - } - else - { - if (iwt != null) - { - sil = get_generic_functions(sil, true, subloc); - sil = get_function_instances(sil, iwt.template_params.params_list, id_right.name, subloc, sil.Count() <= 1); - } - #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим - //lroman// - if (lambdas_are_in_parameters) - { - LambdaHelper.processingLambdaParametersForTypeInference++; - // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями - List spf = null; - try - { - function_node ffn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters); - int exprCounter = 0; - if (skip_first_parameter) - { - exprCounter++; - } - List params_exprs = new List(); - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - exprCounter++; - continue; - } - else - { - var enLambda = (SyntaxTree.function_lambda_definition)en; - if (ffn.parameters[Math.Min(exprCounter, ffn.parameters.Count - 1)].is_params) - { - LambdaHelper.InferTypesFromVarStmt(ffn.parameters[Math.Min(exprCounter, ffn.parameters.Count - 1)].type.element_type, enLambda, this); - enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; - if (exprCounter <= ffn.parameters.Count - 1) - exprs[exprCounter] = convert_strong(en); - else - exprs.AddElement(convert_strong(en)); - enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; - } - else - { - LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this); - enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; - exprs[exprCounter] = convert_strong(en); - enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; - - } - exprCounter++; - } - } - /*if (params_exprs.Count > 0) - { - location loc = get_location(_method_call); - typeof_operator to = new typeof_operator(params_exprs[0].type, loc); - expression_node retv = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl, loc, to, new int_const_node(params_exprs.Count, loc)); - base_function_call cnfc = retv as base_function_call; - foreach (expression_node e in params_exprs) - cnfc.parameters.AddElement(e); - exprs[exprCounter] = cnfc; - }*/ - } - catch (SeveralFunctionsCanBeCalled sf) - { - spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна - } - - Exception lastmultex = null; - if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try - { // exprs - глобальная, поэтому надо копировать - int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка - // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. - // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! - int GoodVersionsCount = 0; - int GoodVersionsCountWithSameResType = 0; - for (int i = 0; i < spf.Count; i++) // цикл по версиям - { - function_node fnn = spf[i]; - try - { - int exprCounter = 0; - if (skip_first_parameter) - { - exprCounter++; - } - - expressions_list exprs1 = new expressions_list(); - exprs1.AddRange(exprs); // сделали копию - - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - exprCounter++; - continue; - } - else - { - var fld = en as SyntaxTree.function_lambda_definition; - - var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо - var fl = fld.lambda_visit_mode; - - // запомнили типы параметров лямбды - SSM - var fld_formal_parameters_Count = fld.formal_parameters == null ? 0 : fld.formal_parameters.params_list.Count; - - object[] realparamstype = new object[fld_formal_parameters_Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы - for (var k = 0; k < fld_formal_parameters_Count; k++) - { - var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; - if (laminftypeK == null) - realparamstype[k] = null; - else realparamstype[k] = laminftypeK.real_type; - } - - // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим - var restype = fld.return_type as SyntaxTree.lambda_inferred_type; - object realrestype = null; - if (restype != null) - realrestype = restype.real_type; - LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this); - fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman - fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! - - //contextChanger.SaveContextAndUpToNearestDefSect(); - try - { - exprs1[exprCounter] = convert_strong(en); - - type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; - type_node resformaltype = fld.RealSemTypeOfResult as type_node; - var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность - if (bbb) - { - GoodVersionsCountWithSameResType += 1; - spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. - } - - /*compiled_type_node tt; - tt = fnn.parameters[exprCounter].type as compiled_type_node; - if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) - { - resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func - тип возвращаемого значения - var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность - if (bbb) - { - GoodVersionsCountWithSameResType += 1; - spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. - } - }*/ - } - catch - { - throw; - } - finally - { - LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); - // восстанавливаем сохраненный тип возвращаемого значения - if (restype != null) - restype.real_type = realrestype; - // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно - for (var k = 0; k < fld_formal_parameters_Count; k++) - { - var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; - if (laminftypeK != null) - laminftypeK.real_type = realparamstype[k]; - } - - fld.lambda_name = lambdaName; //lroman Восстанавливаем имена - fld.lambda_visit_mode = fl; - } - - //contextChanger.RestoreCurrentContext(); - exprCounter++; - } - } - /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так - { - spfnum = -2; - break; - }*/ - - if (GoodVersionsCountWithSameResType == 0) - spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения - GoodVersionsCount += 1; - for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо - exprs[j] = exprs1[j]; - } - catch (Exception e) - { - // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать - //contextChanger.RestoreCurrentContext(); - lastmultex = e; - } - } // конец цикла по версиям - if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения - throw new SeveralFunctionsCanBeCalled(subloc, spf); - if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд - { - throw lastmultex; - //throw new NoFunctionWithSameArguments(subloc2, false); - } - - int kk = 0; - if (skip_first_parameter) - kk++; - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - kk++; - continue; - } - else - { - LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); - exprs[kk] = convert_strong(en); - kk++; - } - } - } - // SSM 21.05.14 end - LambdaHelper.processingLambdaParametersForTypeInference--; - } - //lroman// - #endregion - - function_node fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters); - - base_function_call bfc2 = null; - if (exp == null) - { - bfc2 = create_static_method_call(fn, subloc, tn, proc_wait); - } - else - { - bfc2 = create_not_static_method_call(fn, exp, subloc, proc_wait); - } - bfc2.parameters.AddRange(exprs); - subexpr2 = bfc2; - } - - visit_mc_helper(mot, subexpr2, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED",true); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(subexpr2); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(subexpr2); - return; - } - default: - { - AddError(subexpr2.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - } */ - } - } - } - else - { - SyntaxTree.expression expr = deref_value as SyntaxTree.expression; - if (expr != null) - { - expression_node exp_int = convert_strong(expr); - location sloc = get_location(expr); - internal_interface ii = exp_int.type.get_internal_interface(internal_interface_kind.delegate_interface); - if (ii == null) - { - AddError(sloc, "EXPECTED_DELEGATE"); - } - delegate_internal_interface dii = (delegate_internal_interface)ii; - sil = new List { new SymbolInfo(dii.invoke_method) }; - - if (_method_call.parameters != null) - { - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) - { - #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов - //lroman// - if (en is SyntaxTree.function_lambda_definition) - { - lambdas_are_in_parameters = true; - ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; - } - //lroman// - #endregion - exprs.AddElement(convert_strong(en)); - } - } - location subloc = sloc; - #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим - //lroman// - if (lambdas_are_in_parameters) - { - LambdaHelper.processingLambdaParametersForTypeInference++; - // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями - List spf = null; - try - { - function_node ffn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters); - int exprCounter = 0; - - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - exprCounter++; - continue; - } - else - { - var enLambda = (SyntaxTree.function_lambda_definition)en; - LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this); - enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; - exprs[exprCounter] = convert_strong(en); - enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; - exprCounter++; - } - } - } - catch (SeveralFunctionsCanBeCalled sf) - { - spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна - } - - Exception lastmultex = null; - if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try - { // exprs - глобальная, поэтому надо копировать - int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка - // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. - // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! - int GoodVersionsCount = 0; - int GoodVersionsCountWithSameResType = 0; - for (int i = 0; i < spf.Count; i++) // цикл по версиям - { - function_node fnn = spf[i]; - try - { - int exprCounter = 0; - - - expressions_list exprs1 = new expressions_list(); - exprs1.AddRange(exprs); // сделали копию - - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - exprCounter++; - continue; - } - else - { - var fld = en as SyntaxTree.function_lambda_definition; - - var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо - var fl = fld.lambda_visit_mode; - - // запомнили типы параметров лямбды - SSM - object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы - for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) - { - var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; - if (laminftypeK == null) - realparamstype[k] = null; - else realparamstype[k] = laminftypeK.real_type; - } - - // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим - var restype = fld.return_type as SyntaxTree.lambda_inferred_type; - object realrestype = null; - if (restype != null) - realrestype = restype.real_type; - LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this); - fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman - fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! - - //contextChanger.SaveContextAndUpToNearestDefSect(); - try - { - exprs1[exprCounter] = convert_strong(en); - - type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; - type_node resformaltype = fld.RealSemTypeOfResult as type_node; - var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность - if (bbb) - { - GoodVersionsCountWithSameResType += 1; - spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. - } - - /*compiled_type_node tt; - tt = fnn.parameters[exprCounter].type as compiled_type_node; - if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) - { - resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func - тип возвращаемого значения - var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность - if (bbb) - { - GoodVersionsCountWithSameResType += 1; - spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. - } - }*/ - } - catch - { - throw; - } - finally - { - LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); - // восстанавливаем сохраненный тип возвращаемого значения - if (restype != null) - restype.real_type = realrestype; - // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно - for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) - { - var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; - if (laminftypeK != null) - laminftypeK.real_type = realparamstype[k]; - } - - fld.lambda_name = lambdaName; //lroman Восстанавливаем имена - fld.lambda_visit_mode = fl; - } - - //contextChanger.RestoreCurrentContext(); - exprCounter++; - } - } - /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так - { - spfnum = -2; - break; - }*/ - - if (GoodVersionsCountWithSameResType == 0) - spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения - GoodVersionsCount += 1; - for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо - exprs[j] = exprs1[j]; - } - catch (Exception e) - { - // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать - //contextChanger.RestoreCurrentContext(); - lastmultex = e; - } - } // конец цикла по версиям - if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения - throw new SeveralFunctionsCanBeCalled(subloc, spf); - if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд - { - throw lastmultex; - //throw new NoFunctionWithSameArguments(subloc2, false); - } - - int kk = 0; - - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - kk++; - continue; - } - else - { - LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); - exprs[kk] = convert_strong(en); - kk++; - } - } - } - // SSM 21.05.14 end - LambdaHelper.processingLambdaParametersForTypeInference--; - } - //lroman// - #endregion - - function_node del_func = convertion_data_and_alghoritms.select_function(exprs, sil, sloc, syntax_nodes_parameters); - base_function_call bbfc = create_not_static_method_call(del_func, exp_int, sloc, proc_wait); - bbfc.parameters.AddRange(exprs); - - visit_mc_helper(mot, bbfc, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED",true); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(bbfc); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(bbfc); - return; - } - default: - { - AddError(bbfc.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - } */ - } - else - { - throw new CompilerInternalError("Unexpected method name kind"); - } - } - } - } - - //definition_node dn=check_name_node_type(id.name,si,get_location(_method_call),general_node_type.function_node); - - expression_node exp2 = null; - location subloc2 = get_location(id); - - List sibak = new List(); - if (sil != null) - sibak.AddRange(sil.GetRange(1, sil.Count() - 1)); - - if (sil == null) - { - AddError(new UndefinedNameReference(id.name, subloc2)); - } - - is_format_allowed = false; - if (SystemUnitAssigned) - { - if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(sil) || SystemLibrary.SystemLibInitializer.readln_procedure.Equal(sil)) - { - - expression_node bfcint = make_read_call(sil, _method_call.parameters, subloc2); - if (!proc_wait) - AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (sil.FirstOrDefault().sym_info as function_node).name); - - visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(bfcint); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(bfcint); - return; - } - default: - { - AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - }*/ - - return; - } - else if (SystemLibrary.SystemLibInitializer.write_procedure.Equal(sil) || SystemLibrary.SystemLibInitializer.writeln_procedure.Equal(sil) || SystemLibrary.SystemLibInitializer.StrProcedure.Equal(sil)) - { - is_format_allowed = true; - } - else if (SystemLibrary.SystemLibInitializer.PascalABCVersion.Equal(sil)) - { - return_value(new string_const_node(RevisionClass.FullVersion, get_location(_method_call))); - return; - } - else if (SystemLibrary.SystemLibInitializer.ArrayCopyFunction.Equal(sil)) - { - if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1) - { - expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); - if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_kind) - { - location loc = get_location(_method_call); - expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ArrayCopyFunction.sym_info as function_node, loc, param0); - function_node fn = convertion_data_and_alghoritms.get_empty_conversion(en.type, param0.type, false); - en = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, en); - return_value(en); - return; - } - } - } - else if (SystemLibrary.SystemLibInitializer.SetLengthProcedure.Equal(sil) || SystemLibrary.SystemLibrary.resize_func == sil.FirstOrDefault().sym_info as function_node) - { - if (_method_call.parameters != null && _method_call.parameters.expressions.Count >= 2) - { - expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); - if (!param0.is_addressed) - AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); - if (param0.type.type_special_kind == SemanticTree.type_special_kind.short_string) - { - expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); - param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.integer_type); - base_function_call cnfn = null; - if (SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info is common_namespace_function_node) - cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); - else - cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info as compiled_function_node, get_location(_method_call)); - cnfn.parameters.AddElement(param0); - cnfn.parameters.AddElement(param1); - cnfn.parameters.AddElement(new int_const_node((param0.type as short_string_type_node).Length, null)); - - visit_mc_helper(mot, cnfn, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(cnfn); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(cnfn); - return; - } - default: - { - AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - } */ - } - else if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_kind) - { - int rank = 1; - if (param0.type is compiled_type_node) - rank = (param0.type as compiled_type_node).rank; - else if (param0.type is common_type_node) - rank = (param0.type as common_type_node).rank; - if (_method_call.parameters.expressions.Count - 1 != rank) - AddError(get_location(_method_call), "{0}_PARAMETERS_EXPECTED", rank + 1); - if (rank > 1) - { - type_node tn = param0.type.element_type; - location loc = get_location(_method_call); - typeof_operator to = new typeof_operator(tn, loc); - List lst = new List(); - //размер - for (int i = 1; i < _method_call.parameters.expressions.Count; i++) - { - expression_node expr = convert_strong(_method_call.parameters.expressions[i]); ; - expr = convertion_data_and_alghoritms.convert_type(expr, SystemLibrary.SystemLibrary.integer_type); - if (expr is int_const_node && (expr as int_const_node).constant_value < 0) - AddError(expr.location, "NEGATIVE_ARRAY_LENGTH_({0})_NOT_ALLOWED", (expr as int_const_node).constant_value); - lst.Add(expr); - } - //это вызов спецфункции - - expression_node retv = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl, loc, to, new int_const_node(lst.Count, loc)); - common_namespace_function_call cnfc = retv as common_namespace_function_call; - foreach (expression_node e in lst) - cnfc.parameters.AddElement(e); - expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CopyWithSizeFunction.sym_info as function_node, loc, param0, cnfc); - function_node fn = convertion_data_and_alghoritms.get_empty_conversion(en.type, retv.type, false); - en = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, en); - basic_function_call bfc = new basic_function_call(tn.find(compiler_string_consts.assign_name).FirstOrDefault().sym_info as basic_function_node, loc, param0, en); - return_value(bfc); - return; - } - } - } - } - else if (SystemLibrary.SystemLibInitializer.InsertProcedure.Equal(sil)) - { - if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 3) - { - //expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); - expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); - //expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); - if (param1.type.type_special_kind == SemanticTree.type_special_kind.short_string) - { - expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); - expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); - param0 = convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.string_type); - param2 = convertion_data_and_alghoritms.convert_type(param2, SystemLibrary.SystemLibrary.integer_type); - base_function_call cnfn = null; - if (SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info is common_namespace_function_node) - cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); - else - cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info as compiled_function_node, get_location(_method_call)); - cnfn.parameters.AddElement(param0); - cnfn.parameters.AddElement(param1); - cnfn.parameters.AddElement(param2); - cnfn.parameters.AddElement(new int_const_node((param1.type as short_string_type_node).Length, null)); - - visit_mc_helper(mot, cnfn, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(cnfn); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(cnfn); - return; - } - default: - { - AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - }*/ - } - } - } - else if (SystemLibrary.SystemLibInitializer.DeleteProcedure.Equal(sil)) - { - if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 3) - { - //expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); - expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); - //expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); - if (param0.type.type_special_kind == SemanticTree.type_special_kind.short_string) - { - expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); - expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); - param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.integer_type); - param2 = convertion_data_and_alghoritms.convert_type(param2, SystemLibrary.SystemLibrary.integer_type); - base_function_call cnfn = null; - if (SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info is common_namespace_function_node) - cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); - else - cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info as compiled_function_node, get_location(_method_call)); - cnfn.parameters.AddElement(param0); - cnfn.parameters.AddElement(param1); - cnfn.parameters.AddElement(param2); - - visit_mc_helper(mot, cnfn, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(cnfn); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(cnfn); - return; - } - default: - { - AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - } */ - } - } - } - else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil) - || SystemLibrary.SystemLibInitializer.ExcludeProcedure.Equal(sil)) - { - if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 2) - { - expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); - expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); - param1 = convert_if_typed_expression_to_function_call(param1); - expressions_list args = new expressions_list(); - args.AddElement(param0); - args.AddElement(param1); - CheckSpecialFunctionCall(sil, args, get_location(_method_call)); - expression_node en_cnfn = null; - if (SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info is common_namespace_function_node) - { - common_namespace_function_call cnfn = null; - if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil)) cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); - else cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ExcludeProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); - cnfn.parameters.AddElement(param0); - cnfn.parameters.AddElement(param1); - en_cnfn = cnfn; - } - else - { - compiled_static_method_call cnfn = null; - if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil)) cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info as compiled_function_node, get_location(_method_call)); - else cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ExcludeProcedure.sym_info as compiled_function_node, get_location(_method_call)); - cnfn.parameters.AddElement(param0); - cnfn.parameters.AddElement(param1); - en_cnfn = cnfn; - } - - visit_mc_helper(mot, en_cnfn, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(en_cnfn); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(en_cnfn); - return; - } - default: - { - AddError(en_cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - } */ - } - } - else if (SystemLibrary.SystemLibInitializer.IncProcedure.Equal(sil)) - { - expression_node bfcint = make_inc_call(sil?.FirstOrDefault(), _method_call.parameters, subloc2); - if (!proc_wait) - AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (sil.FirstOrDefault().sym_info as function_node).name); - - visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(bfcint); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(bfcint); - return; - } - default: - { - AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - } */ - - return; - } - else if (SystemLibrary.SystemLibInitializer.DecProcedure.Equal(sil)) - { - expression_node bfcint = make_dec_call(sil?.FirstOrDefault(), _method_call.parameters, subloc2); - if (!proc_wait) - AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (sil.FirstOrDefault().sym_info as function_node).name); - - visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(bfcint); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(bfcint); - return; - } - default: - { - AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - }*/ - - return; - } - else if (SystemLibrary.SystemLibInitializer.SuccFunction.Equal(sil)) - { - expression_node bfcint = make_succ_call(sil, _method_call.parameters, subloc2); - - visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(bfcint); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(bfcint); - return; - } - default: - { - AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - }*/ - - return; - } - else if (SystemLibrary.SystemLibInitializer.PredFunction.Equal(sil)) - { - expression_node bfcint = make_pred_call(sil, _method_call.parameters, subloc2); - visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(bfcint); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(bfcint); - return; - } - default: - { - AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - } */ - - return; - } - else if (SystemLibrary.SystemLibInitializer.OrdFunction.Equal(sil)) - { - expression_node bfcint = make_ord_call(sil, _method_call.parameters, subloc2); - visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(bfcint); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(bfcint); - return; - } - default: - { - AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - } */ - - return; - } - else if (SystemLibrary.SystemLibInitializer.LowFunction.Equal(sil)) - { - if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1) - { - expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); - if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper) - { - bounded_array_interface bai = param0.type.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface; - expression_node en = new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), get_location(_method_call)); - - visit_mc_helper(mot, en, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(en); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(en); - return; - } - default: - { - AddError(en.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - }*/ - } - } - } - else if (SystemLibrary.SystemLibInitializer.HighFunction.Equal(sil)) - { - if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1) - { - expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); - if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper) - { - bounded_array_interface bai = param0.type.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface; - expression_node en = new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.upper_value), get_location(_method_call)); - - visit_mc_helper(mot, en, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(en); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(en); - return; - } - default: - { - AddError(en.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - } */ - } - } - } - else if (sil.FirstOrDefault() == SystemLibrary.SystemLibInitializer.NewProcedure) - { - expression_node bfcint = make_new_call(sil.FirstOrDefault(), _method_call.parameters, subloc2); - if (!proc_wait) - AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (sil.FirstOrDefault().sym_info as function_node).name); - - visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(bfcint); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(bfcint); - return; - } - default: - { - AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - }*/ - - return; - } - else if (sil.FirstOrDefault() == SystemLibrary.SystemLibInitializer.DisposeProcedure) - { - //if (convertion_data_and_alghoritms.select_function(convert_expression_list(_method_call.parameters.expressions), si, subloc2) == SystemLibrary.SystemLibInitializer.DisposeProcedure.sym_info) - //{ - expression_node bfcint = make_dispose_call(sil.FirstOrDefault(), _method_call.parameters, subloc2); - if (!proc_wait) - AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (sil.FirstOrDefault().sym_info as function_node).name); - - visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(bfcint); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(bfcint); - return; - } - default: - { - AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); - return; - } - }*/ - - return; - // } - } - else if (SystemLibrary.SystemLibInitializer.AssertProcedure.Equal(sil)) - { - // return_value(new empty_statement(null)); - // return; - } - /*else if (SystemLibrary.SystemLibInitializer.IncProcedure != null && SystemLibrary.SystemLibInitializer.IncProcedure.Equal(si)) - { - expression_node bfcint = make_inc_call(si, _method_call.parameters, subloc2); - }*/ - } - if (sil.FirstOrDefault().sym_info.general_node_type != general_node_type.function_node) - { - if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.type_node) - { - to_type = ((type_node)(sil.FirstOrDefault().sym_info)); - /*if (to_type == SystemLibrary.SystemLibrary.void_type) - { - throw new VoidNotValid(subloc2); - }*/ - check_for_type_allowed(to_type, subloc2); - } - else - { - exp2 = ident_value_reciving(sil, id); - internal_interface ii = exp2.type.get_internal_interface(internal_interface_kind.delegate_interface); - if (ii == null) - { - AddError(subloc2, "EXPECTED_DELEGATE"); - } - if (exp2 is nonstatic_event_reference) - { - nonstatic_event_reference nser = exp2 as nonstatic_event_reference; - common_event ce = nser.en as common_event; - if (ce != null) - exp2 = new class_field_reference(ce.field, new this_node(ce.cont_type, null), null); - else - AddError(get_location(_method_call), "EVENT_{0}_MUST_BE_IN_LEFT_PART", nser.en.name); - } - else if (exp2 is static_event_reference) - { - static_event_reference nser = exp2 as static_event_reference; - common_event ce = nser.en as common_event; - if (ce != null) - exp2 = new static_class_field_reference(ce.field, null); - else if (nser.en is common_namespace_event && _compiled_unit.namespaces.IndexOf((nser.en as common_namespace_event).namespace_node) != -1) - exp2 = new namespace_variable_reference((nser.en as common_namespace_event).field, null); - else - AddError(get_location(_method_call), "EVENT_{0}_MUST_BE_IN_LEFT_PART", nser.en.name); - } - delegate_internal_interface dii = ii as delegate_internal_interface; - sil = new List { new SymbolInfo(dii.invoke_method) }; - } - } - - if (to_type != null) - { - if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1)) - { - AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED"); - } - if (proc_wait && to_type.IsDelegate) - { - var mc = new SyntaxTree.method_call(new SyntaxTree.expression_list()); - mc.dereferencing_value = _method_call; - procedure_wait = true; - visit(mc); - return; - } - } - - if (_method_call.parameters != null) - { - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) - { - bool tmp = is_format_allowed; - - #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов - //lroman// - if (en is SyntaxTree.function_lambda_definition) - { - lambdas_are_in_parameters = true; - ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode .VisitForInitialMethodCallProcessing; - } - //lroman// - #endregion - - expression_node sem_en = convert_strong(en); - exprs.AddElement(sem_en); - is_format_allowed = tmp; - } - if (SystemLibrary.SystemLibInitializer.AssertProcedure != null && SystemLibrary.SystemLibInitializer.AssertProcedure.Equal(sil) && _method_call.source_context != null) - { - exprs.AddElement(new string_const_node(_method_call.source_context.FileName, null)); - exprs.AddElement(new int_const_node(_method_call.source_context.begin_position.line_num, null)); - } - } - is_format_allowed = false; - CheckSpecialFunctionCall(sil, exprs, get_location(_method_call)); - - sil.RemoveRange(1, sil.Count() - 1); - sil.AddRange(sibak); - - if (to_type != null) - { - //(ssyy) К вызову функции здесь явно не приводим, т.к. это излишне. - expression_node ee = exprs[0]; - bool del = to_type is common_type_node && (to_type as common_type_node).IsDelegate; - - if (!del) - try_convert_typed_expression_to_function_call(ref ee); - else - ee = convert_strong(_method_call.parameters.expressions[0]); - - expr_node = convertion_data_and_alghoritms.explicit_convert_type(ee, to_type); - - //expression_node expr = convert_if_typed_expression_to_function_call(exprs[0]); - //expr_node = convertion_data_and_alghoritms.explicit_convert_type(expr, to_type); - } - else - { - #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим - //lroman// - if (lambdas_are_in_parameters) - { - LambdaHelper.processingLambdaParametersForTypeInference++; - var sil2 = sil; - location mcloc = get_location(_method_call); - if (iwt != null) - { - sil2 = get_generic_functions(sil, true, mcloc); - sil2 = get_function_instances(sil2, iwt.template_params.params_list, id.name, mcloc, sil2.Count() <= 1); - } - // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями - List spf = null; - try - { - function_node fn = convertion_data_and_alghoritms.select_function(exprs, sil2, subloc2, syntax_nodes_parameters); - int exprCounter = 0; - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - exprCounter++; - continue; - } - else - { - var enLambda = (SyntaxTree.function_lambda_definition)en; - if (fn.parameters[exprCounter].is_params) - LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type.element_type, enLambda, this); - else - LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type, enLambda, this); - enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; - exprs[exprCounter] = convert_strong(en); - enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; - exprCounter++; - } - } - } - catch (SeveralFunctionsCanBeCalled sf) - { - spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна - } - - Exception lastmultex = null; - if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try - { // exprs - глобальная, поэтому надо копировать - int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка - // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. - // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! И еще выше по коду!!! кошмар!!! - int GoodVersionsCount = 0; - int GoodVersionsCountWithSameResType = 0; - for (int i = 0; i < spf.Count; i++) // цикл по версиям - { - function_node fn = spf[i]; - try // внутренний try регенерирует исключение, а этот гасит - { - int exprCounter = 0; - expressions_list exprs1 = new expressions_list(); - exprs1.AddRange(exprs); // сделали копию - - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - exprCounter++; - continue; - } - else - { - var fld = en as SyntaxTree.function_lambda_definition; - - var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо - var fl = fld.lambda_visit_mode; - - // запомнили типы параметров лямбды - SSM - var cnt = fld.formal_parameters?.params_list?.Count ?? 0; // SSM 22.06.19 - object[] realparamstype = new object[cnt]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы - for (var k = 0; k < cnt; k++) - { - var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; - if (laminftypeK == null) - realparamstype[k] = null; - else realparamstype[k] = laminftypeK.real_type; - } - - // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим - var restype = fld.return_type as SyntaxTree.lambda_inferred_type; - object realrestype = null; - if (restype != null) - realrestype = restype.real_type; - - LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type, fld, this); - fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman - fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! - - //contextChanger.SaveContextAndUpToNearestDefSect(); - try - { - exprs1[exprCounter] = convert_strong(en); - - // SSM 7/08/15 - - type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; - type_node resformaltype = fld.RealSemTypeOfResult as type_node; - var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность - if (bbb) - { - GoodVersionsCountWithSameResType += 1; - spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. - } - - /*var tt = fn.parameters[exprCounter].type as compiled_type_node; - if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) - { - resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func - тип возвращаемого значения - var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность - if (bbb) - { - GoodVersionsCountWithSameResType += 1; - spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. - } - }*/ - } - catch - { - throw; - } - finally - { - LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); - // восстанавливаем сохраненный тип возвращаемого значения - if (restype != null) - restype.real_type = realrestype; - // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно - for (var k = 0; k < (fld.formal_parameters?.params_list?.Count ?? 0); k++) - { - var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; - if (laminftypeK != null) - laminftypeK.real_type = realparamstype[k]; - } - - fld.lambda_name = lambdaName; //lroman Восстанавливаем имена - fld.lambda_visit_mode = fl; - } - - //contextChanger.RestoreCurrentContext(); - exprCounter++; - } - } - /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так - { - spfnum = -2; - break; - }*/ - - if (GoodVersionsCountWithSameResType == 0) - spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения - GoodVersionsCount += 1; - for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо - exprs[j] = exprs1[j]; - } - catch (Exception e) - { - // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать - //contextChanger.RestoreCurrentContext(); - lastmultex = e; - } - } //--------------- конец цикла по версиям - - if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения - throw new SeveralFunctionsCanBeCalled(subloc2, spf); - if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд - { - throw lastmultex; - //throw new NoFunctionWithSameArguments(subloc2, false); - } - - var kk = 0; - foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - kk++; - continue; - } - else - { - LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); - exprs[kk] = convert_strong(en); - kk++; - } - } - } - // SSM 21.05.14 end - LambdaHelper.processingLambdaParametersForTypeInference--; - } - //lroman// - #endregion - if (exp2 == null) - { - location mcloc = get_location(_method_call); - if (iwt != null) - { - sil = get_generic_functions(sil, true, mcloc); - sil = get_function_instances(sil, iwt.template_params.params_list, id.name, mcloc, sil.Count() <= 1); - } - - - - // #2180 - в уникальной ситуации, когда из метода потомка вызывается метод расширения класса-предка добавлять Self (!) - // Это значит, что dereferencing_value - это идентификатор и sil состоит только (?) из методов расширения - // Надо разделить на две части - для методов расширения добавлять Self. а для не методов - не добавлять - // В первом случае окаймить всё try catch и погашать исключение - if (_method_call.dereferencing_value is ident) - { - var silNoExt = sil.Select(s => s.sym_info).Where(s => s is function_node fn && !fn.is_extension_method).ToList(); - var silExt = sil.Select(s => s.sym_info).Where(s => s is function_node fn && fn.is_extension_method).ToList(); - - if (silNoExt.Count > 0) - { - try - { - expr_node = convertion_data_and_alghoritms.create_full_function_call(exprs, sil, mcloc, - context.converted_type, context.top_function, proc_wait, _method_call.parameters?.expressions); - } - catch (Exception e) - { - if (e is CompilationErrorWithLocation && (e as CompilationErrorWithLocation).loc == null) - (e as CompilationErrorWithLocation).loc = mcloc; - if (silExt.Count == 0) - throw; // не проверять в методах расширения, поскольку их нет - } - - } - // Сюда мы пришли либо с expr_node != null и тогда в методах расширения искать не надо даже если они есть - // либо с expr_node == null и тогда всё будет определяться методами расширения - if (silExt.Count > 0 && expr_node == null) - { - var en0 = convert_strong(new ident("Self",_method_call.dereferencing_value.source_context)); - exprs.AddElementFirst(en0); - expr_node = convertion_data_and_alghoritms.create_full_function_call(exprs, sil, mcloc, - context.converted_type, context.top_function, proc_wait, _method_call.parameters?.expressions); - } - } - else - expr_node = convertion_data_and_alghoritms.create_full_function_call(exprs, sil, mcloc, - context.converted_type, context.top_function, proc_wait, _method_call.parameters?.expressions); - } - else - { - function_node fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc2, syntax_nodes_parameters); - base_function_call bbffcc = create_not_static_method_call(fn, exp2, subloc2, proc_wait); - bbffcc.parameters.AddRange(exprs); - expr_node = bbffcc; - } - } - - /*if ((proc_wait==false)&&(expr_node.type==null)) - { - throw new FunctionExpectedProcedureMeet((function_node)dn,get_location(_method_call)); - }*/ - - visit_mc_helper(mot, expr_node, expr_node.location, exprs, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO",true); - return; - - - /*switch (mot) - { - case motivation.expression_evaluation: - { - return_value(expr_node); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(expr_node); - return; - } - case motivation.address_receiving: - { - AddError(get_location(_method_call), "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); - return; - } - default: - { - //throw new CompilerInternalError("Can not recive address from method call");//! - AddError(get_location(_method_call), "EXPECTED_VARIABLE"); - return; - } - }*/ - //throw new CompilerInternalError("Error in creation method call"); - - } - - //remove extension methods when static methods called - private void delete_extension_methods(ref List sil, type_node tn) - { - List si_list = new List(); - if (sil != null) - { - foreach (SymbolInfo si in sil) - { - var fn = si.sym_info as function_node; - if (fn != null) - { - if (fn.is_extension_method) - { - compiled_function_node cfn = fn as compiled_function_node; - if (cfn != null && cfn.cont_type == tn) - si_list.Add(si); - } - else - si_list.Add(si); - } - else - si_list.Add(si); - /*if (!(fn != null && fn.is_extension_method)) - si_list.Add(tmp_si);*/ - } - sil = si_list; - if(si_list.Count == 0) - sil = null; - } - /*tmp_si = si; - while (tmp_si != null) - { - var fn = tmp_si.sym_info as function_node; - if (fn != null && fn.is_extension_method) - { - var b = false; - foreach (var x in si_list) - { - var xn = x.sym_info as function_node; - if (convertion_data_and_alghoritms.function_eq_params(fn, xn)) - { - b = true; - break; - } - } - if (!b) - si_list.Add(tmp_si); - } - tmp_si = tmp_si.Next; - }*/ - } - - //ssyy - //Удаляет конструкторы предков в списке si - private void delete_inherited_constructors(ref List si, type_node tn) - { - int cur_ind = 0; - while (si!= null && cur_ind < si.Count()) - { - type_node comph_type = null; - bool is_ctor = false; - common_method_node mnode = si[cur_ind].sym_info as common_method_node; - if (mnode != null) - { - comph_type = mnode.cont_type; - is_ctor = mnode.is_constructor; - } - else - { - compiled_function_node tnode = si[cur_ind].sym_info as compiled_function_node; - if (tnode != null) - { - comph_type = tnode.cont_type; - is_ctor = tnode.method_info.IsConstructor; - } - } - //Итак, comph_type - класс, содержащий si.sym_info; - //is_ctor - является ли оно конструктором - if (is_ctor && comph_type != tn) - { - //Удаляем - si.RemoveAt(cur_ind); - } - else - ++cur_ind; - } - if (si != null && si.FirstOrDefault() == null) - si = null; - } - //\ssyy - - //TODO: Возможно следует переписать этот метод в более простой форме. - public override void visit(SyntaxTree.method_call _method_call) - { - visit_method_call(_method_call); - inherited_ident_processing = false; - } - - private void ConvertPointersForWrite(expressions_list exprs) - { - for (int i = 0; i < exprs.Count; ++i) - { - if (exprs[i].type.IsPointer) - { - if (SystemLibrary.SystemLibInitializer.PointerOutputConstructor == null) - { - List sil = (SystemLibrary.SystemLibInitializer.PointerOutputType.sym_info as common_type_node).find_in_type(compiler_string_consts.default_constructor_name); - common_method_node cnode = null; - int cur_si_ind = 0; - do - { - cnode = sil[cur_si_ind].sym_info as common_method_node; - if (cnode.parameters.Count != 1) - { - cnode = null; - ++cur_si_ind; - } - } - while (cnode == null); - SystemLibrary.SystemLibInitializer.PointerOutputConstructor = cnode; - } - common_constructor_call cnc = new common_constructor_call(SystemLibrary.SystemLibInitializer.PointerOutputConstructor as common_method_node, exprs[i].location); - //common_namespace_function_call cnfc = new common_namespace_function_call( - // SystemLibrary.SystemLibInitializer.PointerToStringFunction.sym_info as common_namespace_function_node, - // exprs[i].location); - cnc.parameters.AddElement(exprs[i]); - exprs[i] = cnc; - } - } - } - - private void ConvertPointersForWriteFromDll(expressions_list exprs) - { - for (int i = 0; i < exprs.Count; ++i) - { - if (exprs[i].type.IsPointer) - { - if (SystemLibrary.SystemLibInitializer.PointerOutputConstructor == null) - { - List sil = (SystemLibrary.SystemLibInitializer.PointerOutputType.sym_info as compiled_type_node).find_in_type(compiler_string_consts.default_constructor_name); - compiled_constructor_node cnode = null; - int cur_si_index = 0; - do - { - cnode = sil[cur_si_index].sym_info as compiled_constructor_node; - if (cnode.parameters.Count != 1) - { - cnode = null; - ++cur_si_index; - } - } - while (cnode == null); - SystemLibrary.SystemLibInitializer.PointerOutputConstructor = cnode; - } - compiled_constructor_call cnc = new compiled_constructor_call(SystemLibrary.SystemLibInitializer.PointerOutputConstructor as compiled_constructor_node, exprs[i].location); - //common_namespace_function_call cnfc = new common_namespace_function_call( - // SystemLibrary.SystemLibInitializer.PointerToStringFunction.sym_info as common_namespace_function_node, - // exprs[i].location); - cnc.parameters.AddElement(exprs[i]); - exprs[i] = cnc; - } - } - } - - private void CheckSpecialFunctionCall(List sil, expressions_list exprs, location loc) - { - if (SystemUnitAssigned) - { - bool write_proc = SystemLibrary.SystemLibInitializer.write_procedure.Equal(sil); - if (write_proc && exprs.Count > 1) - { - //возможно это запись в типизированый файл - if (exprs[0].type.type_special_kind == SemanticTree.type_special_kind.typed_file) - //да, точно это типизированый файл! - { - //Проверим типы параметров вызова на совпадение с типом элементов файла - type_node element_type = exprs[0].type.element_type; - for (int i = 1; i < exprs.Count; i++) - convertion_data_and_alghoritms.check_convert_type(exprs[i], element_type, exprs[i].location); - if (element_type.type_special_kind == SemanticTree.type_special_kind.short_string) - { - for (int i = 1; i < exprs.Count; i++) - { - //common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node,null); - //cmc.parameters.AddElement(exprs[i]); - //cmc.parameters.AddElement(new int_const_node((element_type as short_string_type_node).Length,null)); - expression_node cmc = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node, null, convertion_data_and_alghoritms.convert_type(exprs[i], SystemLibrary.SystemLibrary.string_type), new int_const_node((element_type as short_string_type_node).Length, null)); - exprs[i] = cmc; - } - } - //if (exprs[i].type != element_type) - // throw new ExpectedExprHaveTypeTypedFile(element_type, exprs[i].type, false, get_location(_method_call.parameters.expressions[i])); - } - else - //(ssyy) а может быть, в бинарный! - if (exprs[0].type.type_special_kind == SemanticTree.type_special_kind.binary_file) - { - //(ssyy) действительно, бинарный - for (int i = 1; i < exprs.Count; i++) - { - if (!CanUseThisTypeForBinaryFiles(exprs[i].type)) - { - AddError(exprs[i].location, "CAN_NOT_WRITE_REFERENCE_DATA_TO_BINARY_FILE"); - } - } - } - else - { - if (SystemLibrary.SystemLibInitializer.write_procedure.sym_info is common_namespace_function_node) - ConvertPointersForWrite(exprs); - else - ConvertPointersForWriteFromDll(exprs); - } - } - else if (write_proc || SystemLibrary.SystemLibInitializer.writeln_procedure.Equal(sil)) - { - //(ssyy) Преобразуем указатели в строки для вывода write/writeln - if (SystemLibrary.SystemLibInitializer.writeln_procedure.sym_info is common_namespace_function_node) - ConvertPointersForWrite(exprs); - else - ConvertPointersForWriteFromDll(exprs); - } - else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil) - || SystemLibrary.SystemLibInitializer.ExcludeProcedure.Equal(sil)) - { - if (exprs.Count != 2) AddError(new NoFunctionWithSameArguments(loc, true)); - type_node element_type = exprs[0].type.element_type; - if (exprs[0].type.type_special_kind != SemanticTree.type_special_kind.base_set_type && exprs[0].type.type_special_kind != SemanticTree.type_special_kind.set_type) - { - AddError(new NoFunctionWithSameArguments(loc, true)); - } - if (element_type != null) - convertion_data_and_alghoritms.check_convert_type(exprs[1], element_type, exprs[1].location); - else convertion_data_and_alghoritms.check_convert_type(exprs[1], exprs[0].type, exprs[0].location); - if (!exprs[0].is_addressed) AddError(new ThisExpressionCanNotBePassedAsVarParameter(exprs[0])); - } - else if (SystemLibrary.SystemLibInitializer.InSetProcedure.Equal(sil)) - { - if (exprs.Count != 2) AddError(new NoFunctionWithSameArguments(loc, true)); - type_node element_type = exprs[1].type.element_type; - if (element_type != null) - { - //exprs[0] = convertion_data_and_alghoritms.convert_type(exprs[0], element_type, exprs[0].location); - convertion_data_and_alghoritms.check_convert_type(exprs[0], element_type, exprs[0].location); - } - else convertion_data_and_alghoritms.check_convert_type(exprs[0], exprs[1].type, exprs[0].location); - } - else if (SystemLibrary.SystemLibInitializer.SetUnionProcedure.Equal(sil) - || SystemLibrary.SystemLibInitializer.SetIntersectProcedure.Equal(sil) || SystemLibrary.SystemLibInitializer.SetSubtractProcedure.Equal(sil)) - { - if (exprs.Count != 2) AddError(new NoFunctionWithSameArguments(loc, true)); - convertion_data_and_alghoritms.check_convert_type(exprs[1], exprs[0].type, exprs[1].location); - } - - if (sil.FirstOrDefault() == SystemLibrary.SystemLibInitializer.NewProcedure || sil.FirstOrDefault() == SystemLibrary.SystemLibInitializer.DisposeProcedure) - { - if (exprs[0].type == SystemLibrary.SystemLibrary.pointer_type) - AddError(exprs[0].location, "EXPECTED_TYPED_POINTER_IN_PROCEDURE{0}", (sil.FirstOrDefault().sym_info as function_node).name); - } - } - } - - private expression_node make_new_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc) - { - if (parameters == null) AddError( new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node)); - if (parameters.expressions.Count == 1) - { - expression_node param0 = convert_strong(parameters.expressions[0]); - if (!param0.type.IsPointer || param0.type == SystemLibrary.SystemLibrary.pointer_type) - AddError(new NoFunctionWithSameArguments(loc, true)); - if (!param0.is_addressed) - { - bool is_pascal_array_ref = false; - if (param0.semantic_node_type == semantic_node_type.common_method_call) - { - common_method_call cmc = (common_method_call)param0; - internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); - if (ii != null) - { - if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) - { - bounded_array_interface bai = (bounded_array_interface)ii; - class_field cf = bai.int_array; - expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); - expression_node right = cmc.parameters[0]; - //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); - right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); - right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, - new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); - param0 = new simple_array_indexing(left, right, cmc.type, cmc.location); - is_pascal_array_ref = true; - } - } - if (!is_pascal_array_ref) - { - AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); - } - - } - else AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); - } - if (param0.type is ref_type_node && !can_evaluate_size((param0.type as ref_type_node).pointed_type)) - AddError(loc, "CANNOT_CALL_NEW_BECAUSE_OF_UNDEFINED_SIZE"); - function_node fn = si.sym_info as function_node; - common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); - cnfc.parameters.AddElement(param0); - return cnfc; - - } - else - { - AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node)); - return null; - } - } - - private expression_node make_dispose_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc) - { - if (parameters == null) - { - AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node)); - return null; - } - if (parameters.expressions.Count == 1) - { - expression_node param0 = convert_strong(parameters.expressions[0]); - if (!param0.type.IsPointer || param0.type == SystemLibrary.SystemLibrary.pointer_type) - AddError(new NoFunctionWithSameArguments(loc, true)); - if (!param0.is_addressed) - { - bool is_pascal_array_ref = false; - if (param0.semantic_node_type == semantic_node_type.common_method_call) - { - common_method_call cmc = (common_method_call)param0; - internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); - if (ii != null) - { - if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) - { - bounded_array_interface bai = (bounded_array_interface)ii; - class_field cf = bai.int_array; - expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); - expression_node right = cmc.parameters[0]; - //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); - right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); - right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, - new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); - param0 = new simple_array_indexing(left, right, cmc.type, cmc.location); - is_pascal_array_ref = true; - } - } - if (!is_pascal_array_ref) - { - AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); - return null; - } - - } - else - { - AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); - return null; - } - } - function_node fn = si.sym_info as function_node; - common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); - cnfc.parameters.AddElement(param0); - return cnfc; - - } - else - { - AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node)); - return null; - } - } - - private expression_node make_ord_call(List sil, SyntaxTree.expression_list parameters, location loc) - { - if (parameters == null) - { - AddError(new NoFunctionWithSameParametresNum(loc, false, sil.FirstOrDefault().sym_info as function_node)); - return null; - } - if (parameters.expressions.Count == 1) - { - expression_node param0 = convert_strong(parameters.expressions[0]); - if (param0 is typed_expression) param0 = convert_typed_expression_to_function_call(param0 as typed_expression); - - expressions_list el = new expressions_list(); - el.AddElement(param0); - function_node fn = null; - try - { - fn = convertion_data_and_alghoritms.select_function(el, sil, loc); - } - catch (Exception e) - { - - } - if (fn != null) - { - if (fn is common_namespace_function_node) - { - common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); - cnfc.parameters.AddElement(param0); - return cnfc; - } - else - { - compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc); - cnfc.parameters.AddElement(param0); - return cnfc; - } - } - else if (param0.type.IsEnum || param0.type.type_special_kind == SemanticTree.type_special_kind.diap_type) - { - el = new expressions_list(); - el.AddElement(new int_const_node(1, null)); - fn = convertion_data_and_alghoritms.select_function(el, sil, loc); - //bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); - //bfc.ret_type = param0.type; - if (fn is common_namespace_function_node) - { - common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); - cnfc.parameters.AddElement(param0); - return cnfc; - } - else - { - compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc); - cnfc.parameters.AddElement(param0); - return cnfc; - } - } - - else - { - AddError(new NoFunctionWithSameArguments(loc, false)); - return null; - } - } - else - { - AddError(new NoFunctionWithSameParametresNum(loc, false, sil.FirstOrDefault().sym_info as function_node)); - return null; - } - } - - private expression_node make_succ_call(List sil, SyntaxTree.expression_list parameters, location loc) - { - if (parameters == null) - { - AddError(new NoFunctionWithSameParametresNum(loc, false, sil.FirstOrDefault().sym_info as function_node)); - return null; - } - if (parameters.expressions.Count == 1) - { - expression_node param0 = convert_strong(parameters.expressions[0]); - if (param0 is typed_expression) param0 = convert_typed_expression_to_function_call(param0 as typed_expression); - basic_function_call bfc = null; - int type_flag = 0; - expressions_list el = new expressions_list(); - el.AddElement(param0); - function_node fn = null; - try - { - fn = convertion_data_and_alghoritms.select_function(el,sil,loc); - } - catch(Exception e) - { - - } - if (fn != null) - { - if (fn is common_namespace_function_node) - { - common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); - cnfc.parameters.AddElement(param0); - return cnfc; - } - else - { - compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc); - cnfc.parameters.AddElement(param0); - return cnfc; - } - } - if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || param0.type.IsEnum) - { - el = new expressions_list(); - el.AddElement(new int_const_node(1,null)); - fn = convertion_data_and_alghoritms.select_function(el,sil,loc); - //bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); - //bfc.ret_type = param0.type; - if (fn is common_namespace_function_node) - { - common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); - cnfc.parameters.AddElement(param0); - cnfc.type = param0.type; - return cnfc; - } - else - { - compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc); - cnfc.parameters.AddElement(param0); - cnfc.type = param0.type; - return cnfc; - } - } - else AddError(new NoFunctionWithSameArguments(loc,false)); - bfc.parameters.AddElement(param0); - if (type_flag == 0 || type_flag == 3) - bfc.parameters.AddElement(new int_const_node(1,null)); - else if (type_flag == 1) - bfc.parameters.AddElement(new long_const_node(1,null)); - else if (type_flag == 2) - bfc.parameters.AddElement(new ulong_const_node(1,null)); - return bfc; - } - AddError(new NoFunctionWithSameParametresNum(loc,false,sil.FirstOrDefault().sym_info as function_node)); - return null; - } - - private expression_node make_pred_call(List sil, SyntaxTree.expression_list parameters, location loc) - { - if (parameters == null) - { - AddError(new NoFunctionWithSameParametresNum(loc, false, sil.FirstOrDefault().sym_info as function_node)); - return null; - } - if (parameters.expressions.Count == 1) - { - expression_node param0 = convert_strong(parameters.expressions[0]); - if (param0 is typed_expression) param0 = convert_typed_expression_to_function_call(param0 as typed_expression); - basic_function_call bfc = null; - int type_flag = 0; - expressions_list el = new expressions_list(); - el.AddElement(param0); - function_node fn = null; - try - { - fn = convertion_data_and_alghoritms.select_function(el,sil,loc); - } - catch(Exception e) - { - - } - if (fn != null) - { - if (fn is common_namespace_function_node) - { - common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); - cnfc.parameters.AddElement(param0); - return cnfc; - } - else - { - compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc); - cnfc.parameters.AddElement(param0); - return cnfc; - } - } - else if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || param0.type.IsEnum) - { - el = new expressions_list(); - el.AddElement(new int_const_node(1,null)); - fn = convertion_data_and_alghoritms.select_function(el,sil,loc); - //bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); - //bfc.ret_type = param0.type; - if (fn is common_namespace_function_node) - { - common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); - cnfc.parameters.AddElement(param0); - cnfc.type = param0.type; - return cnfc; - } - else - { - compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc); - cnfc.parameters.AddElement(param0); - cnfc.type = param0.type; - return cnfc; - } - } - else AddError(new NoFunctionWithSameArguments(loc,false)); - bfc.parameters.AddElement(param0); - if (type_flag == 0 || type_flag == 3) - bfc.parameters.AddElement(new int_const_node(1,null)); - else if (type_flag == 1) - bfc.parameters.AddElement(new long_const_node(1,null)); - else if (type_flag == 2) - bfc.parameters.AddElement(new ulong_const_node(1,null)); - return bfc; - } - AddError(new NoFunctionWithSameParametresNum(loc,false,sil.FirstOrDefault().sym_info as function_node)); - return null; - } - - private expression_node make_inc_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc) - { - if (parameters == null) - { - AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node)); - return null; - } - if (parameters.expressions.Count == 1 || parameters.expressions.Count == 2) - { - expression_node param0 = convert_strong(parameters.expressions[0]); - if (!param0.is_addressed) - { - bool is_pascal_array_ref = false; - if (param0.semantic_node_type == semantic_node_type.common_method_call) - { - common_method_call cmc = (common_method_call)param0; - internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); - if (ii != null) - { - if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) - { - bounded_array_interface bai = (bounded_array_interface)ii; - class_field cf = bai.int_array; - expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); - expression_node right = cmc.parameters[0]; - //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); - right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); - right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, - new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); - param0 = new simple_array_indexing(left, right, cmc.type, cmc.location); - is_pascal_array_ref = true; - } - } - if (!is_pascal_array_ref) - { - AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); - } - - } - else if (param0 is compiled_function_call) - { - compiled_function_call cfc = param0 as compiled_function_call; - if ((cfc.function_node.return_value_type == SystemLibrary.SystemLibrary.char_type && cfc.function_node.cont_type == SystemLibrary.SystemLibrary.string_type - && cfc.function_node == cfc.function_node.cont_type.default_property_node.get_function)) - { - expressions_list exl = new expressions_list(); - exl.AddElement(cfc.obj); - exl.AddElement(cfc.parameters[0]); - basic_function_call bfc2 = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); - bfc2.parameters.AddElement(param0); - expression_node _param1 = null; - if (parameters.expressions.Count == 2) - { - _param1 = convert_strong(parameters.expressions[1]); - } - if (_param1 != null) - bfc2.parameters.AddElement(convertion_data_and_alghoritms.convert_type(_param1,SystemLibrary.SystemLibrary.integer_type)); - else - bfc2.parameters.AddElement(new int_const_node(1,null)); - expressions_list el = new expressions_list(); - el.AddElement(convertion_data_and_alghoritms.convert_type(bfc2,SystemLibrary.SystemLibrary.ushort_type)); - function_node chr_func = convertion_data_and_alghoritms.select_function(el, SystemLibrary.SystemLibInitializer.ChrUnicodeFunction.SymbolInfo, loc); - exl.AddElement(convertion_data_and_alghoritms.create_simple_function_call(chr_func, loc, el.ToArray())); - function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure.SymbolInfo, loc); - expression_node ret = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, exl.ToArray()); - return ret; - } - else - { - AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); - } - } - else AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); - } - else - check_on_loop_variable(param0); - expression_node param1 = null; - int type_flag = 0; - bool is_uint = false; - bool is_enum = false; - if (parameters.expressions.Count == 2) - { - param1 = convert_strong(parameters.expressions[1]); - //param1 = convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type); - } - basic_function_call ass = null; - basic_function_call bfc = null; - if (param0.type == SystemLibrary.SystemLibrary.integer_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); - } - else if (param0.type == SystemLibrary.SystemLibrary.char_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.char_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); - } - else if (param0.type == SystemLibrary.SystemLibrary.byte_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.byte_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); - } - else if (param0.type == SystemLibrary.SystemLibrary.sbyte_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.sbyte_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); - } - else if (param0.type == SystemLibrary.SystemLibrary.short_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.short_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); - } - else if (param0.type == SystemLibrary.SystemLibrary.ushort_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.ushort_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); - } - else if (param0.type == SystemLibrary.SystemLibrary.uint_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.uint_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.uint_add as basic_function_node,loc); - type_flag = 2; - is_uint = true; - } - else if (param0.type == SystemLibrary.SystemLibrary.int64_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.long_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.long_add as basic_function_node,loc); - type_flag = 1; - } - else if (param0.type == SystemLibrary.SystemLibrary.uint64_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.ulong_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.ulong_add as basic_function_node,loc); - type_flag = 2; - } - else if (param0.type == SystemLibrary.SystemLibrary.bool_type) - { - if (param1 == null) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc); - type_flag = 4; - } - else - { - basic_function_call mod_expr = new basic_function_call(SystemLibrary.SystemLibrary.int_mod as basic_function_node,loc); - mod_expr.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type)); - mod_expr.parameters.AddElement(new int_const_node(2,loc)); - basic_function_call condition = new basic_function_call(SystemLibrary.SystemLibrary.int_eq as basic_function_node,loc); - condition.parameters.AddElement(mod_expr); - condition.parameters.AddElement(new int_const_node(0,loc)); - basic_function_call not_expr = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc); - not_expr.parameters.AddElement(param0); - question_colon_expression qce = new question_colon_expression(condition, param0, not_expr, loc); - ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc); - ass.parameters.AddElement(param0); - ass.parameters.AddElement(qce); - type_flag = 5; - } - } - else if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || param0.type.IsEnum) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); - if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) - { - type_node bt = param0.type.base_type; - if (bt == SystemLibrary.SystemLibrary.int64_type) type_flag = 1; - else if (bt == SystemLibrary.SystemLibrary.uint64_type) type_flag = 2; - else if (bt == SystemLibrary.SystemLibrary.uint_type) - { - type_flag =2; - is_uint = true; - } - else if (bt.IsEnum) - { - is_enum = true; - } - } - else if (param0.type.IsEnum) is_enum = true; - } - else AddError(new NoFunctionWithSameArguments(loc,false)); - if (type_flag != 5) - { - if (param1 != null) - switch (type_flag) - { - case 0: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.integer_type); break; - case 3: - case 1: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.int64_type); break; - case 2: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.uint64_type); break; - } - if (param0.type != SystemLibrary.SystemLibrary.char_type && !is_enum && param0.type != SystemLibrary.SystemLibrary.bool_type) - switch (type_flag) - { - case 0: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.integer_type)); break; - case 3: - case 1: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.int64_type)); break; - case 2: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.uint64_type)); break; - } - - else bfc.parameters.AddElement(param0); - //bfc.parameters.AddElement(param0); - - if (param1 == null) - { - if (type_flag == 0 || type_flag == 3) - bfc.parameters.AddElement(new int_const_node(1, null)); - else if (type_flag == 1) - bfc.parameters.AddElement(new long_const_node(1, null)); - else if (type_flag == 2) - bfc.parameters.AddElement(new ulong_const_node(1, null)); - } - else - bfc.parameters.AddElement(param1); - ass.parameters.AddElement(param0); - if (is_uint) - ass.parameters.AddElement(convertion_data_and_alghoritms.convert_type(bfc, SystemLibrary.SystemLibrary.uint_type)); - else - if (param0.type == SystemLibrary.SystemLibrary.char_type) - { - expressions_list el = new expressions_list(); - el.AddElement(convertion_data_and_alghoritms.convert_type(bfc, SystemLibrary.SystemLibrary.ushort_type)); - function_node chr_func = convertion_data_and_alghoritms.select_function(el, SystemLibrary.SystemLibInitializer.ChrUnicodeFunction.SymbolInfo, loc); - ass.parameters.AddElement(convertion_data_and_alghoritms.create_simple_function_call(chr_func, loc, el.ToArray())); - } - else - ass.parameters.AddElement(bfc); - } - return ass; - } - - AddError(new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node)); - return null; - } - - private expression_node make_dec_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc) - { - if (parameters == null) throw new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node); - if (parameters.expressions.Count == 1 || parameters.expressions.Count == 2) - { - expression_node param0 = convert_strong(parameters.expressions[0]); - if (!param0.is_addressed) - { - bool is_pascal_array_ref = false; - if (param0.semantic_node_type == semantic_node_type.common_method_call) - { - common_method_call cmc = (common_method_call)param0; - internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); - if (ii != null) - { - if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) - { - bounded_array_interface bai = (bounded_array_interface)ii; - class_field cf = bai.int_array; - expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); - expression_node right = cmc.parameters[0]; - //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); - right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); - right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, - new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); - param0 = new simple_array_indexing(left, right, cmc.type, cmc.location); - is_pascal_array_ref = true; - - } - } - if (!is_pascal_array_ref) - { - throw new ThisExpressionCanNotBePassedAsVarParameter(param0); - } - - } - else if (param0 is compiled_function_call) - { - compiled_function_call cfc = param0 as compiled_function_call; - if ((cfc.function_node.return_value_type == SystemLibrary.SystemLibrary.char_type && cfc.function_node.cont_type == SystemLibrary.SystemLibrary.string_type - && cfc.function_node == cfc.function_node.cont_type.default_property_node.get_function)) - { - expressions_list exl = new expressions_list(); - exl.AddElement(cfc.obj); - exl.AddElement(cfc.parameters[0]); - basic_function_call bfc2 = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); - bfc2.parameters.AddElement(param0); - expression_node _param1 = null; - if (parameters.expressions.Count == 2) - { - _param1 = convert_strong(parameters.expressions[1]); - } - if (_param1 != null) - bfc2.parameters.AddElement(convertion_data_and_alghoritms.convert_type(_param1,SystemLibrary.SystemLibrary.integer_type)); - else - bfc2.parameters.AddElement(new int_const_node(1,null)); - expressions_list el = new expressions_list(); - el.AddElement(convertion_data_and_alghoritms.convert_type(bfc2,SystemLibrary.SystemLibrary.ushort_type)); - function_node chr_func = convertion_data_and_alghoritms.select_function(el,SystemLibrary.SystemLibInitializer.ChrUnicodeFunction.SymbolInfo, loc); - exl.AddElement(convertion_data_and_alghoritms.create_simple_function_call(chr_func, loc, el.ToArray())); - function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure.SymbolInfo, loc); - expression_node ret = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, exl.ToArray()); - return ret; - } - else - { - throw new ThisExpressionCanNotBePassedAsVarParameter(param0); - } - } - else throw new ThisExpressionCanNotBePassedAsVarParameter(param0); - } - else - check_on_loop_variable(param0); - expression_node param1 = null; - int type_flag = 0; - bool is_uint=false; - bool is_enum=false; - if (parameters.expressions.Count == 2) - { - param1 = convert_strong(parameters.expressions[1]); - param1 = convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type); - } - basic_function_call ass = null; - basic_function_call bfc = null; - if (param0.type == SystemLibrary.SystemLibrary.integer_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); - } - else if (param0.type == SystemLibrary.SystemLibrary.char_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.char_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); - } - else if (param0.type == SystemLibrary.SystemLibrary.byte_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.byte_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); - } - else if (param0.type == SystemLibrary.SystemLibrary.sbyte_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.sbyte_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); - } - else if (param0.type == SystemLibrary.SystemLibrary.short_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.short_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); - } - else if (param0.type == SystemLibrary.SystemLibrary.ushort_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.ushort_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); - } - else if (param0.type == SystemLibrary.SystemLibrary.uint_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.uint_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.uint_sub as basic_function_node,loc); - type_flag = 2; - is_uint = true; - } - else if (param0.type == SystemLibrary.SystemLibrary.int64_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.long_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.long_sub as basic_function_node,loc); - type_flag = 1; - } - else if (param0.type == SystemLibrary.SystemLibrary.uint64_type) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.ulong_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.ulong_sub as basic_function_node,loc); - type_flag = 2; - } - else if (param0.type == SystemLibrary.SystemLibrary.bool_type) - { - if (param1 == null) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc); - type_flag = 4; - } - else - { - basic_function_call mod_expr = new basic_function_call(SystemLibrary.SystemLibrary.int_mod as basic_function_node,loc); - mod_expr.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type)); - mod_expr.parameters.AddElement(new int_const_node(2,loc)); - basic_function_call condition = new basic_function_call(SystemLibrary.SystemLibrary.int_eq as basic_function_node,loc); - condition.parameters.AddElement(mod_expr); - condition.parameters.AddElement(new int_const_node(0,loc)); - basic_function_call not_expr = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc); - not_expr.parameters.AddElement(param0); - question_colon_expression qce = new question_colon_expression(condition, param0, not_expr, loc); - ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc); - ass.parameters.AddElement(param0); - ass.parameters.AddElement(qce); - type_flag = 5; - } - } - else if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || param0.type.IsEnum) - { - ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc); - bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); - if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) - { - type_node bt = param0.type.base_type; - if (bt == SystemLibrary.SystemLibrary.int64_type) type_flag = 1; - else if (bt == SystemLibrary.SystemLibrary.uint64_type) type_flag = 2; - else if (bt == SystemLibrary.SystemLibrary.uint_type) - { - type_flag =2; - is_uint = true; - } - else if (bt.IsEnum) is_enum = true; - } - else if (param0.type.IsEnum) is_enum = true; - } - else throw new NoFunctionWithSameArguments(loc,false); - if (type_flag != 5) - { - if (param1 != null) - switch (type_flag) - { - case 0: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.integer_type); break; - case 3: - case 1: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.int64_type); break; - case 2: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.uint64_type); break; - } - //bfc.parameters.AddElement(param0); - if (param0.type != SystemLibrary.SystemLibrary.char_type && !is_enum && param0.type != SystemLibrary.SystemLibrary.bool_type) - switch (type_flag) - { - case 0: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.integer_type)); break; - case 3: - case 1: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.int64_type)); break; - case 2: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.uint64_type)); break; - } - else bfc.parameters.AddElement(param0); - if (param1 == null) - { - if (type_flag == 0 || type_flag == 3) - bfc.parameters.AddElement(new int_const_node(1, null)); - else if (type_flag == 1) - bfc.parameters.AddElement(new long_const_node(1, null)); - else if (type_flag == 2) - bfc.parameters.AddElement(new ulong_const_node(1, null)); - } - else bfc.parameters.AddElement(param1); - ass.parameters.AddElement(param0); - if (is_uint) - ass.parameters.AddElement(convertion_data_and_alghoritms.convert_type(bfc, SystemLibrary.SystemLibrary.uint_type)); - else - ass.parameters.AddElement(bfc); - } - return ass; - } - - throw new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node); - } - - private void check_on_loop_variable(expression_node en) - { - if (context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable) - if (en.semantic_node_type == semantic_node_type.namespace_variable_reference) - { - if (context.is_loop_variable((en as namespace_variable_reference).var)) - AddError(en.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE"); - } - else if (en.semantic_node_type == semantic_node_type.local_variable_reference) - { - if (context.is_loop_variable((en as local_variable_reference).var)) - AddError(en.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE"); - } - else if (en.semantic_node_type == semantic_node_type.local_block_variable_reference) - { - if (context.is_loop_variable((en as local_block_variable_reference).var)) - AddError(en.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE"); - } - - } - - private expression_node make_read_call(List sil, SyntaxTree.expression_list parameters, location loc) - { - - // вызов read(a,b,c) разбивается на несколько вызовов, последний возвращается узлом, а остальные добавляются здесь в теле expressions_list exl = new expressions_list(); - expression_node last_call = null; - expressions_list exl = new expressions_list(); - expression_node file = null; - bool read_from_file = false; - bool read_from_text_file = false; - bool read_from_typed_file = false; - bool read_from_binary_file = false; - bool readln_string_file = false; - if (parameters != null) // если список параметров не пуст - { - if (parameters.expressions.Count >= 1) - { - expression_node param0 = convert_strong(parameters.expressions[0]); - if (param0.type != null) - { - if (SystemLibrary.SystemLibInitializer.TextFileType.Found && param0.type == SystemLibrary.SystemLibInitializer.TextFileType.sym_info) - { - file = param0; - read_from_text_file = true; - } - if (param0.type.type_special_kind == SemanticTree.type_special_kind.typed_file - && parameters.expressions.Count > 1 //это можно внести во внутрь - )//и побросать приличные исключения - { - if (!SystemLibrary.SystemLibInitializer.read_procedure.FromDll) - { - if (sil.SequenceEqual(SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo)) - { - file = param0; - read_from_typed_file = true; - } - } - else if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(sil)) - { - file = param0; - read_from_typed_file = true; - } - } - if (param0.type.type_special_kind == SemanticTree.type_special_kind.binary_file - && parameters.expressions.Count > 1 //это можно внести во внутрь - )//и побросать приличные исключения - { - if (!SystemLibrary.SystemLibInitializer.read_procedure.FromDll) - { - if (sil.SequenceEqual(SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo)) - { - file = param0; - read_from_binary_file = true; - } - } - else if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(sil)) - { - file = param0; - read_from_binary_file = true; - } - } - } - read_from_file = read_from_text_file || read_from_typed_file || read_from_binary_file; - } - bool first_iteration = true; - - foreach (SyntaxTree.expression ex in parameters.expressions) - { - if (first_iteration && read_from_file) - { - first_iteration = false; - continue; - } - if (last_call != null && convertion_data_and_alghoritms.statement_list_stack.size > 0) - convertion_data_and_alghoritms.statement_list_stack.top().statements.AddElement(last_call); - expression_node en = convert_strong(ex); - check_on_loop_variable(en); - //if (en.type == null) - //throw new CanNotRead(en.location); - exl.clear(); - if (read_from_file) - exl.AddElement(file); - if (read_from_typed_file) - { - if (SystemLibrary.SystemLibInitializer.TypedFileReadProcedure == null) - AddError(new NotSupportedError(loc)); - if (en.type != file.type.element_type) - AddError(new ExpectedExprHaveTypeTypedFile(file.type.element_type, en.type, true, get_location(ex))); - bool is_char_getter = false; - if (!en.is_addressed) - { - if (en is compiled_function_call) - { - compiled_function_call cfc = en as compiled_function_call; - - if ((cfc.function_node.return_value_type == SystemLibrary.SystemLibrary.char_type && cfc.function_node.cont_type == SystemLibrary.SystemLibrary.string_type - && cfc.function_node == cfc.function_node.cont_type.default_property_node.get_function)) - { - en = new simple_array_indexing((en as compiled_function_call).obj, (en as compiled_function_call).parameters[0], SystemLibrary.SystemLibrary.char_type, en.location); - is_char_getter = true; - } - - } - } - function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.TypedFileReadProcedure.SymbolInfo, loc); - expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), file); - //expression_node expr = convertion_data_and_alghoritms.create_full_function_call(exl, SystemLibrary.SystemLibInitializer.TypedFileReadProcedure.SymbolInfo, loc, context.converted_type, context.top_function, true); - expr = convertion_data_and_alghoritms.explicit_convert_type(expr, file.type.element_type); - if (is_char_getter) - expr = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure.sym_info as function_node, loc, (en as simple_array_indexing).simple_arr_expr, (en as simple_array_indexing).ind_expr, expr); - else - expr = find_operator(compiler_string_consts.assign_name, en, expr, loc); - last_call = expr; - } - else if (read_from_binary_file) - { - if (SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure == null) - AddError(new NotSupportedError(loc)); - if (!CanUseThisTypeForBinaryFiles(en.type)) - { - AddError(en.location, "CAN_NOT_READ_REFERENCE_DATA_FROM_BINARY_FILE"); - } - exl.AddElement(new typeof_operator(en.type, loc)); - function_node fn = convertion_data_and_alghoritms.select_function(exl,SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure.SymbolInfo, loc); - expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray()); - expr = convertion_data_and_alghoritms.explicit_convert_type(expr, en.type); - expr = find_operator(compiler_string_consts.assign_name, en, expr, loc); - last_call = expr; - } - else - { - exl.AddElement(en); - try - { - function_node fn = null; - if (en.type.type_special_kind == SemanticTree.type_special_kind.short_string) - { - exl.AddElement(new int_const_node((en.type as short_string_type_node).Length,null)); - if (!read_from_file) - last_call = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.read_short_string_procedure.sym_info as function_node,get_location(ex),exl.ToArray()); - else - last_call = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.read_short_string_from_file_procedure.sym_info as function_node,get_location(ex),exl.ToArray()); - } - else if (en.type.type_special_kind == SemanticTree.type_special_kind.diap_type) - { - exl.remove(en); - en.type = en.type.base_type; - exl.AddElement(en); - fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc); - last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray()); - } - else - { - /// SSM 21/05/16 - read_from_text_file && - bug fix #161 - if (read_from_text_file && SystemLibrary.SystemLibInitializer.readln_procedure.Equal(sil) && parameters.expressions.Count == 2 && en.type == SystemLibrary.SystemLibrary.string_type) - { - fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.readln_procedure.SymbolInfo, loc); - readln_string_file = true; - } - else - fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc); - last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray()); - } - //last_call = convertion_data_and_alghoritms.create_full_function_call(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc, context.converted_type, context.top_function, true); - } - catch (NoFunctionWithSameArguments) - { - AddError(en.location, "CAN_NOT_READ"); - } - } - first_iteration = false; - } - } - if ((parameters == null) || (parameters.expressions.Count == 0)) // read(), readln() - { - if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(sil)) - { - if (read_from_file) - exl.AddElement(file); - function_node fn = convertion_data_and_alghoritms.select_function(exl, - SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc); - if (read_from_file) - last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, file); - else - last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc); - } - } - if (SystemLibrary.SystemLibInitializer.readln_procedure.Equal(sil)) // readln(...) - { - if (!readln_string_file) - { - if (last_call != null && convertion_data_and_alghoritms.statement_list_stack.size > 0) - convertion_data_and_alghoritms.statement_list_stack.top().statements.AddElement(last_call); - exl.clear(); - - if (read_from_file) - exl.AddElement(file); - - function_node fn = convertion_data_and_alghoritms.select_function(exl, - SystemLibrary.SystemLibInitializer.readln_procedure.SymbolInfo, loc); - if (read_from_file) - last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, file); - else - last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc); - } - } - return last_call; - } - - internal expression_node GetCurrentObjectReference(SymbolTable.Scope scope, definition_node dn, location loc) - { - if (context.WithSection) - if (scope != null) - if (context.WithVariables.ContainsKey(scope)) - return context.WithVariables[scope]; - else - if (context.WithTypes.Contains(scope)) - { - switch (dn.semantic_node_type) - { - case semantic_node_type.class_field : if (!(dn as class_field).IsStatic) AddError(new CanNotReferenceToNonStaticFieldWithType(dn as class_field,loc,null)); break; - case semantic_node_type.compiled_variable_definition : if (!(dn as compiled_variable_definition).IsStatic) AddError(new CanNotReferenceToNonStaticFieldWithType(dn as class_field,loc,null)); break; - case semantic_node_type.compiled_property_node: - case semantic_node_type.common_property_node : if ((dn as property_node).polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(new CanNotReferenceToNonStaticPropertyWithType(dn as property_node,loc,null)); break; - case semantic_node_type.compiled_function_node: - case semantic_node_type.common_method_node: if ((dn as function_node).polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(new CanNotReferenceToNonStaticMethodWithType((dn as function_node).name,loc)); break; - } - } - if (context.inStaticArea()) - { - AddError(new CanNotReferenceToNonStaticFromStatic(dn,loc)); - return null; - } - else - return new this_node(context.converted_type, loc); - } - - - private expression_node create_with_expression(expression_node expr) - { - location sl = expr.location; - switch (expr.semantic_node_type) - { - case semantic_node_type.common_namespace_function_call: - case semantic_node_type.common_in_function_function_call: - case semantic_node_type.common_method_call: - case semantic_node_type.common_static_method_call: - case semantic_node_type.compiled_function_call: - case semantic_node_type.compiled_constructor_call: - case semantic_node_type.common_constructor_call: - case semantic_node_type.compiled_static_method_call: - return convertion_data_and_alghoritms.CreateVariableReference(context.add_var_definition(compiler_string_consts.GetTempVariableName(), sl, expr.type, expr), sl); - case semantic_node_type.class_field_reference: - (expr as class_field_reference).obj = create_with_expression((expr as class_field_reference).obj); - return expr; - case semantic_node_type.compiled_variable_reference: - (expr as compiled_variable_reference).obj = create_with_expression((expr as compiled_variable_reference).obj); - return expr; - case semantic_node_type.simple_array_indexing: - simple_array_indexing sar = expr as simple_array_indexing; - sar.simple_arr_expr = create_with_expression(sar.simple_arr_expr); - sar.ind_expr = create_with_expression(sar.ind_expr); - return sar; - case semantic_node_type.deref_node: - (expr as dereference_node).deref_expr = create_with_expression((expr as dereference_node).deref_expr); - return expr; - case semantic_node_type.basic_function_call: - return convertion_data_and_alghoritms.CreateVariableReference(context.add_var_definition(compiler_string_consts.GetTempVariableName(), sl, expr.type, expr), sl); - case semantic_node_type.as_node: - return convertion_data_and_alghoritms.CreateVariableReference(context.add_var_definition(compiler_string_consts.GetTempVariableName(), sl, expr.type, expr), sl); - } - return expr; - } - - public override void visit(SyntaxTree.with_statement _with_statement) - { - context.WithSection = true; - List Withs = new List(); - List VarRefs = new List(); - List WithTypesList = new List(); - statements_list stl = new statements_list(get_location(_with_statement.do_with), null, null); - SymbolTable.WithScope WithScope = new SymbolTable.WithScope(SymbolTable, context.CurrentScope, null); - convertion_data_and_alghoritms.statement_list_stack_push(stl, WithScope); - foreach (SyntaxTree.expression s_expr in _with_statement.do_with.expressions) - { - //expression_node expr = ret.visit(s_expr); - var mot = motivation_keeper.motivation; - motivation_keeper.set_motivation_to_expect_semantic_node(); - semantic_node sn = ret.visit(s_expr as SyntaxTree.syntax_tree_node); - motivation_keeper.reset(); - expression_node expr = sn as expression_node; - if (expr is null_const_node) - AddError(expr.location, "NIL_IN_THIS_CONTEXT_NOT_ALLOWED"); - if (expr is typed_expression) - expr = convert_typed_expression_to_function_call(expr as typed_expression); - if (expr != null) - { - if (expr.type is generic_instance_type_node) - AddError(get_location(s_expr), "UNEXPECTED_EXPRESSION_IN_WITH"); - variable_reference vr = expr as variable_reference; - if (expr.type == null) - AddError(get_location(s_expr), "UNEXPECTED_EXPRESSION_IN_WITH"); - if (expr.type is ref_type_node) - AddError(get_location(s_expr), "UNEXPECTED_EXPRESSION_IN_WITH"); - if (vr == null) - { - location sl = get_location(s_expr); - if (expr.type.type_special_kind != SemanticTree.type_special_kind.record) - vr = convertion_data_and_alghoritms.CreateVariableReference(context.add_var_definition(compiler_string_consts.GetTempVariableName(), sl, expr.type, expr), sl); - else - expr = create_with_expression(expr); - } - if (vr != null && vr is class_field_reference && vr.type.type_special_kind == SemanticTree.type_special_kind.record) - { - vr = null; - expr = create_with_expression(expr); - } - if (vr != null) - { - VarRefs.Add(vr); - if (vr.type.Scope == null) - { - if (vr.type is compiled_type_node) - (vr.type as compiled_type_node).scope = new NetHelper.NetTypeScope((vr.type as compiled_type_node).compiled_type, SystemLibrary.SystemLibrary.symtab); - else - throw new CompilerInternalError("Cannot create With statement because variable reference scope == null"); - } - //если не нужны локальные перекрытия, здесь нужна проверка - Withs.Add(vr.type.Scope); - } - else - { - VarRefs.Add(expr); - Withs.Add(expr.type.Scope); - } - } - else if (sn is type_node) - { - type_node tn = sn as type_node; - if (tn.IsInterface) - AddError(get_location(s_expr), "UNEXPECTED_EXPRESSION_IN_WITH"); - Withs.Add(tn.Scope); - while (tn != null) - { - if (tn.Scope == null && tn is compiled_type_node) - { - (tn as compiled_type_node).init_scope(); - } - WithTypesList.Add(tn.Scope); - tn = tn.base_type; - } - } - else if (sn is compiled_namespace_node) - { - compiled_namespace_node nn = sn as compiled_namespace_node; - Withs.Add(nn.scope); - } - } - WithScope.WithScopes = Withs.ToArray(); - - Dictionary OldWithVariables = new Dictionary(); - foreach (expression_node vr in VarRefs) - { - if (context.WithVariables.ContainsKey(vr.type.Scope)) - { - //перекрытие области - if (OldWithVariables.ContainsKey(vr.type.Scope)) - //Это локальные перекрытия - OldWithVariables[vr.type.Scope] = context.WithVariables[vr.type.Scope]; - else - OldWithVariables.Add(vr.type.Scope, context.WithVariables[vr.type.Scope]); - context.WithVariables[vr.type.Scope] = vr; - } - else - { - //добавляем текущие with - context.WithVariables.Add(vr.type.Scope, vr); - - } - //ivan dobavil dlja bazovyh klassov - type_node tn = vr.type.base_type; - while (tn != null) - { - if (tn.Scope == null && tn is compiled_type_node) - { - (tn as compiled_type_node).init_scope(); - } - if (tn.Scope != null) - if (!context.WithVariables.ContainsKey(tn.Scope)) - context.WithVariables.Add(tn.Scope, vr); - else - { - if (OldWithVariables.ContainsKey(tn.Scope)) - //Это локальные перекрытия - OldWithVariables[tn.Scope] = context.WithVariables[tn.Scope]; - else - OldWithVariables.Add(tn.Scope, context.WithVariables[tn.Scope]); - context.WithVariables[tn.Scope] = vr; - } - tn = tn.base_type; - } - } - - //Ivan dobavil dlja tipov - - foreach (SymbolTable.Scope sc in WithTypesList) - { - if (!context.WithTypes.Contains(sc)) - context.WithTypes.Push(sc); - } - - stl.statements.AddElement(ret.visit(_with_statement.what_do)); - - //восстанавливаем перекрытия - foreach (SymbolTable.Scope sc in OldWithVariables.Keys) - context.WithVariables[sc] = OldWithVariables[sc]; - //удаляем текущие with - foreach (expression_node vr in VarRefs) - { - context.WithVariables.Remove(vr.type.Scope); - type_node tn = vr.type.base_type; - while (tn != null) - { - if (tn.Scope != null && context.WithVariables.ContainsKey(tn.Scope)) - context.WithVariables.Remove(tn.Scope); - tn = tn.base_type; - } - } - foreach (SymbolTable.Scope sc in WithTypesList) - { - context.WithTypes.Pop(); - } - - context.WithSection = context.WithVariables.Count > 0; - - convertion_data_and_alghoritms.statement_list_stack_pop(); - return_value(stl); - } - - public override void visit(SyntaxTree.labeled_statement _labeled_statement) - { - convertion_data_and_alghoritms.check_node_parser_error(_labeled_statement.label_name); - if (_labeled_statement.to_statement is var_statement || _labeled_statement.to_statement is SyntaxTree.assign_var_tuple) - { - var stmt = new SyntaxTree.labeled_statement(_labeled_statement.label_name,new SyntaxTree.empty_statement()); - ReplaceStatementUsingParent(_labeled_statement, new List - {stmt, _labeled_statement.to_statement - }); - ProcessNode(stmt); - return; - } - List sil = context.CurrentScope.FindOnlyInScopeAndBlocks(_labeled_statement.label_name.name); - /*if (_labeled_statement.to_statement is SyntaxTree.var_statement || _labeled_statement.to_statement is SyntaxTree.assign_var_tuple) - { - AddError(get_location(_labeled_statement.label_name), "LABELED_DECLARATION_NOT_ALLOWED"); - }*/ - if (sil == null) - { - AddError(new UndefinedNameReference(_labeled_statement.label_name.name, get_location(_labeled_statement.label_name))); - } - label_node lab = sil.FirstOrDefault().sym_info as label_node; - if (lab == null) - { - AddError(get_location(_labeled_statement.label_name), "IDENT_{0}_IS_NOT_LABEL", _labeled_statement.label_name.name); - } - // SSM - Patch повторного определения меток в подпрограммах при наличии лямбд - if (lambdaProcessingState != LambdaProcessingState.FinishPhase) - if (lab.is_defined) - { - AddError(get_location(_labeled_statement.label_name), "LABEL_{0}_REDEFINED", _labeled_statement.label_name.name); - } - lab.is_defined = true; - lab.comprehensive_code_block = context.block_stack.Peek(); - foreach (goto_statement gs in lab.goto_statements) - { - if (!context.check_can_goto(lab.comprehensive_code_block, gs.comprehensive_code_block) && gs.location != null) - { - AddError(gs.location, "BLOCKED_LABEL_{0}_GOTO", lab.name); - } - } - convertion_data_and_alghoritms.check_node_parser_error(_labeled_statement.to_statement); - statement_node snode = ret.visit((SyntaxTree.statement)_labeled_statement.to_statement); - labeled_statement las = new labeled_statement(lab, snode, get_location(_labeled_statement)); - ret.return_value((statement_node)las); - } - - public override void visit(SyntaxTree.goto_statement _goto_statement) - { - List sil = context.CurrentScope.FindOnlyInScopeAndBlocks(_goto_statement.label.name); - if (sil == null) - { - AddError(new UndefinedNameReference(_goto_statement.label.name, get_location(_goto_statement.label))); - } - label_node lab = sil.FirstOrDefault().sym_info as label_node; - if (lab == null) - { - AddError(get_location(_goto_statement.label), "IDENT_{0}_IS_NOT_LABEL", _goto_statement.label.name); - } - //if (lab.goto_blocked) - //{ - // throw new BlockedLabelGoto(_goto_statement.label.name, get_location(_goto_statement.label)); - //} - goto_statement gs = new goto_statement(lab, get_location(_goto_statement)); - gs.comprehensive_code_block = context.block_stack.Peek(); - lab.goto_statements.Add(gs); - if (lab.comprehensive_code_block != null) - { - // последнее условие - для goto, которые генерируются в автомате yield, не рассматривать эту ошибку - if (!context.check_can_goto(lab.comprehensive_code_block, gs.comprehensive_code_block) && _goto_statement.source_context != null) - { - AddError(gs.location, "BLOCKED_LABEL_{0}_GOTO", lab.name); - } - } - ret.return_value((statement_node)gs); - } - - public override void visit(SyntaxTree.empty_statement _empty_statement) - { - return_value(new empty_statement(get_location(_empty_statement))); - } - - private addressed_expression create_class_static_field_reference(type_node tn, definition_node dn, - SyntaxTree.ident id_right) - { - switch (dn.semantic_node_type) - { - case semantic_node_type.class_field: - { - class_field cf = (class_field)dn; - if (cf.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - { - AddError(new CanNotReferenceToNonStaticFieldWithType(cf, get_location(id_right), tn)); - } - static_class_field_reference scfr = new static_class_field_reference(cf, get_location(id_right)); - return scfr; - } - case semantic_node_type.compiled_variable_definition: - { - compiled_variable_definition cvd = (compiled_variable_definition)dn; - if (cvd.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - { - AddError(new CanNotReferenceToNonStaticFieldWithType(cvd, get_location(id_right), tn)); - } - static_compiled_variable_reference scvr = new static_compiled_variable_reference(cvd, get_location(id_right)); - return scvr; - } - } - throw new CompilerInternalError("Error in create static class field reference."); - } - - private addressed_expression create_addressed_with_type_expression(type_node tn, SyntaxTree.ident id_right, - SymbolInfo si_right) - { - definition_node dn = null; - if (!internal_is_assign) - dn = context.check_name_node_type(id_right.name, si_right, get_location(id_right), - general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node); - else - dn = context.check_name_node_type(id_right.name, si_right, get_location(id_right), - general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node,general_node_type.constant_definition); - if (dn.general_node_type == general_node_type.constant_definition) - AddError(get_location(id_right), "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT"); - switch (dn.general_node_type) - { - case general_node_type.variable_node: - { - return create_class_static_field_reference(tn, dn, id_right); - } - case general_node_type.property_node: - { - property_node pn = (property_node)dn; - if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - { - AddError(new CanNotReferenceToNonStaticPropertyWithType(pn, get_location(id_right), tn)); - } - static_property_reference pr = new static_property_reference(pn, get_location(id_right)); - return pr; - } - case general_node_type.event_node: - { - if (dn.semantic_node_type == semantic_node_type.compiled_event) - { - compiled_event ce = (compiled_event)dn; - if (!ce.is_static) - { - //throw new NonStaticAndStaticEvevnt(); - } - static_event_reference ser = new static_event_reference(ce, get_location(id_right)); - return ser; - } - else if (dn.semantic_node_type == semantic_node_type.common_event) - { - common_event ce = (common_event)dn; - if (!ce.is_static) - { - //throw new NonStaticAndStaticEvevnt(); - } - static_event_reference ser = new static_event_reference(ce, get_location(id_right)); - return ser; - } - else if (dn.semantic_node_type == semantic_node_type.common_namespace_event) - { - common_namespace_event cne = dn as common_namespace_event; - static_event_reference ser = new static_event_reference(cne, get_location(id_right)); - return ser; - } - break; - } - default : return null; - } - throw new CompilerInternalError("Invalid right type expression"); - } - - private expressions_list convert_expression_list(List expr_list) - { - expressions_list exprs = new expressions_list(); - foreach (SyntaxTree.expression en in expr_list) - exprs.AddElement(convert_strong(en)); - return exprs; - } - - - private base_function_call create_static_method_call_with_params(function_node fn, location loc, type_node tn, bool procedure_allowed, expressions_list parametrs) - { - base_function_call bfc = create_static_method_call(fn, loc, tn, procedure_allowed); - bfc.parameters.AddRange(parametrs); - return bfc; - } - private base_function_call create_static_method_call(function_node fn, location loc, type_node tn, bool procedure_allowed) - { - if ((!procedure_allowed) && (fn.return_value_type == null)) - { - AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn.name); - } - if (fn.semantic_node_type == semantic_node_type.common_method_node) - { - common_method_node cmn = (common_method_node)fn; - if (cmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - { - //ssyy изменил - if (!cmn.is_constructor) - { - AddError(new CanNotCallNonStaticMethodWithClass(tn, loc, fn)); - } - if (cmn.cont_type.IsStatic) - AddError(new SimpleSemanticError(loc, "STATIC_CONSTRUCTOR_CALL")); - if (cmn.cont_type.IsAbstract) - AddError(new SimpleSemanticError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", cmn.cont_type.name)); - common_constructor_call csmc2 = new common_constructor_call(cmn, loc); - return csmc2; - //if (cmn.pascal_associated_constructor==null) - //{ - // throw new CanNotCallNonStaticMethodWithClass(tn,loc,fn); - //} - //common_constructor_call csmc2=new common_constructor_call(cmn.pascal_associated_constructor,loc); - //return csmc2; - //\ssyy - } - common_static_method_call csmc = new common_static_method_call(cmn, loc); - return csmc; - } - if (fn.semantic_node_type == semantic_node_type.compiled_function_node) - { - compiled_function_node cfn = (compiled_function_node)fn; - if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - { - AddError(new CanNotCallNonStaticMethodWithClass(tn, loc, fn)); - } - compiled_static_method_call csmc2 = new compiled_static_method_call(cfn, loc); - return csmc2; - } - if (fn.semantic_node_type == semantic_node_type.compiled_constructor_node) - { - compiled_constructor_node ccn = (compiled_constructor_node)fn; - compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc); - return ccc; - } - if (fn.semantic_node_type == semantic_node_type.basic_function_node) - { - return new basic_function_call(fn as basic_function_node, loc); - } - if (fn.semantic_node_type == semantic_node_type.common_namespace_function_node && (fn as common_namespace_function_node).ConnectedToType != null) - { - return new common_namespace_function_call(fn as common_namespace_function_node,loc); - } - if (fn.semantic_node_type == semantic_node_type.indefinite_definition_node) - { - return new indefinite_function_call(fn, loc); - } - throw new CompilerInternalError("Invalid method kind"); - } - - private expression_node create_static_expression(type_node tn, SyntaxTree.ident id_right, - List si_right) - { - definition_node dn = null; - if (si_right?.FirstOrDefault().sym_info is common_event && (si_right?.FirstOrDefault().sym_info as common_event).cont_type == tn) - dn = context.check_name_node_type(id_right.name, si_right?.FirstOrDefault(), get_location(id_right), general_node_type.variable_node, - general_node_type.function_node, general_node_type.property_node, general_node_type.constant_definition, general_node_type.event_node); - else - dn = context.check_name_node_type(id_right.name, si_right?.FirstOrDefault(), get_location(id_right), general_node_type.variable_node, - general_node_type.function_node, general_node_type.property_node, general_node_type.constant_definition); - switch (dn.general_node_type) - { - case general_node_type.variable_node: - { - return create_class_static_field_reference(tn, dn, id_right); - } - case general_node_type.constant_definition: - { - constant_definition_node cdn = (constant_definition_node)dn; - return cdn.const_value.get_constant_copy(get_location(id_right)); - } - case general_node_type.function_node: - { - if (dn is compiled_function_node) - { - if ((dn as compiled_function_node).ConnectedToType == tn) - { - if (si_right.Count() > 1) - { - List temp = new List(); - temp = si_right.GetRange(1, si_right.Count() - 1); - return create_static_expression(tn, id_right, temp); - } - else - AddError(new UndefinedNameReference(id_right.name, get_location(id_right))); - } - } - else if (dn is common_namespace_function_node) - { - if ((dn as common_namespace_function_node).ConnectedToType == tn) - { - if (si_right.Count() > 1) - { - List temp = new List(); - temp = si_right.GetRange(1, si_right.Count() - 1); - return create_static_expression(tn, id_right, temp); - } - else - AddError(new UndefinedNameReference(id_right.name, get_location(id_right))); - } - } - if (dn.semantic_node_type == semantic_node_type.indefinite_definition_node) - { - return new indefinite_reference(dn as indefinite_definition_node, get_location(id_right)); - } - - return make_delegate_wrapper(null, si_right, get_location(id_right), true); - - } - case general_node_type.property_node: - { - property_node pn = (property_node)dn; - if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - { - AddError(new CanNotReferenceToNonStaticPropertyWithType(pn, get_location(id_right), tn)); - } - function_node fn = pn.get_function; - if (fn == null) - { - AddError(new ThisPropertyCanNotBeReaded(pn, get_location(id_right))); - } - location lloc = get_location(id_right); - check_property_no_params(pn, lloc); - return create_static_method_call(fn, lloc, tn, false); - } - case general_node_type.event_node: - { - - static_event_reference ser = new static_event_reference((event_node)dn, get_location(id_right)); - return ser; - } - } - throw new CompilerInternalError("Error in creating static expression."); - } - - private void dot_node_as_type_ident(type_node tn, SyntaxTree.ident id_right, motivation mot) - { - List si_right = tn.find_in_type(id_right.name, context.CurrentScope); - if (si_right == null) - { - AddError(new MemberIsNotDeclaredInType(id_right, get_location(id_right), tn)); - } - switch (mot) - { - case motivation.address_receiving: - { - return_addressed_value(create_addressed_with_type_expression(tn, id_right, si_right?.FirstOrDefault())); - return; - } - case motivation.expression_evaluation: - { - return_value(create_static_expression(tn, id_right, si_right)); - return; - } - case motivation.semantic_node_reciving: - { - if (si_right.FirstOrDefault().sym_info.general_node_type == general_node_type.type_node) - return_semantic_value(si_right.FirstOrDefault().sym_info as type_node); - else - return_semantic_value(create_static_expression(tn, id_right, si_right)); - return; - } - } - throw new CompilerInternalError("Invalid motivation"); - } - - private void dot_node_as_namespace_ident(namespace_node nn, SyntaxTree.ident id_right, motivation mot) - { - List si_right = nn.findOnlyInNamespace(id_right.name); - if (si_right == null) - { - AddError(new MemberIsNotDeclaredInNamespace(id_right, get_location(id_right), nn)); - } - if (si_right.Count > 0 && si_right[0].sym_info == nn) - AddError(new MemberIsNotDeclaredInNamespace(id_right, get_location(id_right), nn)); - switch (mot) - { - case motivation.address_receiving: - { - return_addressed_value(ident_address_reciving(si_right?.FirstOrDefault(), id_right)); - return; - } - case motivation.expression_evaluation: - { - return_value(ident_value_reciving(si_right, id_right)); - return; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(ident_semantic_reciving(si_right, id_right)); - return; - } - } - throw new CompilerInternalError("Unsupported motivation"); - } - - private void dot_node_as_unit_ident(common_unit_node cun, SyntaxTree.ident id_right, motivation mot) - { - dot_node_as_namespace_ident(cun.namespaces[0], id_right, mot); - } - - private void dot_node_as_ident_dot_template_ident(SyntaxTree.ident id_left, SyntaxTree.ident_with_templateparams template_id_right, - motivation mot) - { - List si_left = context.find(id_left.name); - SyntaxTree.ident id_right = template_id_right.name as SyntaxTree.ident; - if (si_left == null) - { - AddError(new UndefinedNameReference(id_left.name, get_location(id_left))); - } - definition_node dn = context.check_name_node_type(id_left.name, si_left?.FirstOrDefault(), get_location(id_left), - general_node_type.constant_definition, general_node_type.function_node, - general_node_type.namespace_node, general_node_type.property_node, - general_node_type.type_node, general_node_type.variable_node, - general_node_type.unit_node); - switch (dn.general_node_type) - { - case general_node_type.constant_definition: - case general_node_type.function_node: - case general_node_type.property_node: - case general_node_type.variable_node: - { - expression_node ex_nd = ident_value_reciving(si_left, id_left); - dot_node_as_expression_dot_template_ident(ex_nd, template_id_right, mot, id_left); - return; - } - case general_node_type.namespace_node: - { - //throw new CompilerInternalError("Unsupported now."); - namespace_node nn = dn as namespace_node; - dot_node_as_namespace_ident(nn, id_right, mot); - return; - } - case general_node_type.type_node: - { - type_node tn = dn as type_node; - dot_node_as_type_ident(tn, id_right, mot); - return; - } - case general_node_type.unit_node: - { - //throw new NotSupportedError(get_location(id_left)); - dot_node_as_unit_ident((common_unit_node)dn, id_right, mot); - return; - } - } - return; - } - - private void dot_node_as_ident_dot_ident(SyntaxTree.ident id_left, SyntaxTree.ident id_right, - motivation mot) - { - List si_left = context.find(id_left.name); - if (si_left == null) - { - AddError(new UndefinedNameReference(id_left.name, get_location(id_left))); - } - definition_node dn = context.check_name_node_type(id_left.name, si_left?.FirstOrDefault(), get_location(id_left), - general_node_type.constant_definition, general_node_type.function_node, - general_node_type.namespace_node, general_node_type.property_node, - general_node_type.type_node, general_node_type.variable_node, - general_node_type.unit_node); - switch (dn.general_node_type) - { - case general_node_type.constant_definition: - case general_node_type.function_node: - case general_node_type.property_node: - case general_node_type.variable_node: - { - expression_node ex_nd = null; - if (id_left is inherited_ident) - ex_nd = inherited_ident_value_reciving(id_left as inherited_ident); - else - ex_nd = ident_value_reciving(si_left, id_left); - dot_node_as_expression_dot_ident(ex_nd, id_right, mot, id_left); - return; - } - case general_node_type.namespace_node: - { - //throw new CompilerInternalError("Unsupported now."); - namespace_node nn = dn as namespace_node; - dot_node_as_namespace_ident(nn, id_right, mot); - return; - } - case general_node_type.type_node: - { - type_node tn = dn as type_node; - dot_node_as_type_ident(tn, id_right, mot); - return; - } - case general_node_type.unit_node: - { - //throw new NotSupportedError(get_location(id_left)); - dot_node_as_unit_ident((common_unit_node)dn, id_right, mot); - return; - } - } - return; - } - - private expression_node convert_if_typed_expression_to_function_call(expression_node expr) - { - if (expr is typed_expression) - return convert_typed_expression_to_function_call(expr as typed_expression); - return expr; - } - - internal expression_node convert_typed_expression_to_function_call(typed_expression te) - { - delegated_methods dm = te.type as delegated_methods; - if (dm == null) - { - return te; - } - base_function_call bfc = dm.empty_param_method; - if (bfc == null) - { - return te; - } - if (bfc.type == null) - return te; - function_node fn = bfc.simple_function_node; - common_namespace_function_node cnfn = fn as common_namespace_function_node; - if ((fn.parameters.Count == 1 || cnfn != null && fn.parameters.Count == 2 && cnfn.ConnectedToType != null) - && (fn.parameters[fn.parameters.Count - 1].is_params || fn.parameters[fn.parameters.Count - 1].default_value != null) - || fn.parameters.Count > 0 && fn.num_of_default_parameters == fn.parameters.Count) - { - fn = convertion_data_and_alghoritms.select_function(bfc.parameters, new List { new SymbolInfo(fn) }, bfc.location); - if (fn.polymorphic_state == SemanticTree.polymorphic_state.ps_static || fn is common_namespace_function_node || fn is basic_function_node) - bfc = convertion_data_and_alghoritms.create_simple_function_call(fn, bfc.location, bfc.parameters.ToArray()) as base_function_call; - else - { - expression_node obj = null; - if (bfc is common_method_call) - obj = (bfc as common_method_call).obj; - else if (bfc is compiled_function_call) - obj = (bfc as compiled_function_call).obj; - bfc = convertion_data_and_alghoritms.create_method_call(fn, bfc.location, obj, bfc.parameters.ToArray()) as base_function_call; - - } - } - else - { - function_node[] empty_param_methods = dm.empty_param_methods; - - List root_sil = new List { new SymbolInfo(empty_param_methods[0]) }; - for (int i = 1; i < empty_param_methods.Length; i++) - { - root_sil.Add(new SymbolInfo(empty_param_methods[i])); - } - compiled_function_node cfn = fn as compiled_function_node; - if ((fn.parameters.Count == 1 || cfn != null && fn.parameters.Count == 2 && cfn.ConnectedToType != null) - && (fn.parameters[fn.parameters.Count - 1].is_params || fn.parameters[fn.parameters.Count - 1].default_value != null)) - { - fn = convertion_data_and_alghoritms.select_function(bfc.parameters, root_sil, bfc.location); - bfc = create_static_method_call_with_params(fn, bfc.location, fn.return_value_type, true, bfc.parameters); - } - else if (fn.parameters.Count == 1 && cfn != null && cfn.ConnectedToType != null) - { - fn = convertion_data_and_alghoritms.select_function(bfc.parameters, root_sil, bfc.location); - bfc = create_static_method_call_with_params(fn, bfc.location, fn.return_value_type, true, bfc.parameters); - } - } - if (bfc is common_method_call) - { - common_method_node cmn = (bfc as common_method_call).function_node; - if (cmn != null && cmn.is_generic_function && !cmn.is_generic_function_instance && cmn.parameters.Count == 0) - { - cmn = (common_method_node)generic_convertions.DeduceFunction(cmn, new expressions_list(), true, context, bfc.location); - bfc = new common_method_call(cmn, (bfc as common_method_call).obj, bfc.location); - } - } - return bfc; - } - - public void try_convert_typed_expression_to_function_call(ref expression_node en) - { - if (en.semantic_node_type == semantic_node_type.typed_expression) - { - en = convert_typed_expression_to_function_call((typed_expression)en); - } - } - - private addressed_expression create_class_field_reference(expression_node en, definition_node dn, SyntaxTree.ident id_right) - { - try_convert_typed_expression_to_function_call(ref en); - if (dn.semantic_node_type == semantic_node_type.class_field) - { - class_field cf = (class_field)dn; - if (cf.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - AddError(new CanNotReferanceToStaticFieldWithExpression(cf, get_location(id_right), en)); - } - class_field_reference cfr = new class_field_reference(cf, en, get_location(id_right)); - //return_value(cfr); - return cfr; - } - if (dn.semantic_node_type == semantic_node_type.compiled_variable_definition) - { - compiled_variable_definition cfd = (compiled_variable_definition)dn; - if (cfd.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - AddError(new CanNotReferanceToStaticFieldWithExpression(cfd, get_location(id_right), en)); - } - compiled_variable_reference cfr2 = new compiled_variable_reference(cfd, en, get_location(id_right)); - //return_value(cfr2); - return cfr2; - } -#if (DEBUG) - throw new CompilerInternalError("Invalid variable kind"); -#endif - return null; - } - - private base_function_call create_not_static_method_call(function_node fn, expression_node en, location loc, bool procedure_allowed) - { - try_convert_typed_expression_to_function_call(ref en); - if ((!procedure_allowed) && (fn.return_value_type == null)) - { - AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn.name); - } - if (fn.semantic_node_type == semantic_node_type.common_method_node) - { - common_method_node cmn = (common_method_node)fn; - if (cmn.is_constructor) - { - AddError(loc, "CAN_NOT_CALL_CONSTRUCTOR_AS_PROCEDURE"); - } - if (cmn.original_function != null && cmn.original_function is compiled_function_node && (cmn.original_function as compiled_function_node).ConnectedToType != null) - { - common_static_method_call csmc = new common_static_method_call(cmn, loc); - return csmc; - } - if (cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - AddError(new CanNotCallStaticMethodWithExpression(en, fn)); - } - - common_method_call cmc = new common_method_call(cmn, en, loc); - cmc.virtual_call = !inherited_ident_processing; - return cmc; - } - if (fn.semantic_node_type == semantic_node_type.compiled_function_node) - { - compiled_function_node cfn = (compiled_function_node)fn; - if (cfn.ConnectedToType != null) - { - compiled_static_method_call csmc = new compiled_static_method_call(cfn, loc); - return csmc; - } - else - { - if (cfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - if (!cfn.is_extension_method) - AddError(new CanNotCallStaticMethodWithExpression(en, fn)); - else - return new compiled_static_method_call(cfn, loc); - } - compiled_function_call cfc = new compiled_function_call(cfn, en, loc); - cfc.virtual_call = !inherited_ident_processing; - return cfc; - } - } - if (fn.semantic_node_type == semantic_node_type.compiled_constructor_node) - { - AddError(loc, "CAN_NOT_CALL_CONSTRUCTOR_AS_PROCEDURE"); - } - if (fn.semantic_node_type == semantic_node_type.common_namespace_function_node && (fn as common_namespace_function_node).ConnectedToType != null) - { - common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node,loc); - //cnfc.parameters.AddElement(en); - return cnfc; - } - if (fn.semantic_node_type == semantic_node_type.indefinite_definition_node) - { - indefinite_function_call ifc = new indefinite_function_call(fn, loc); - return ifc; - } - throw new CompilerInternalError("Invalid method kind"); - } - - private expression_node expression_value_reciving(SyntaxTree.ident id_right, List sil, expression_node en, bool expected_delegate) - { - general_node_type[] node_types; - if (en is this_node || LambdaHelper.IsCapturedSelf(en)) - node_types = new general_node_type[] { general_node_type.variable_node, - general_node_type.function_node, general_node_type.property_node, general_node_type.constant_definition, general_node_type.event_node}; - else - node_types = new general_node_type[] { general_node_type.variable_node, - general_node_type.function_node, general_node_type.property_node, general_node_type.constant_definition}; - definition_node dn = context.check_name_node_type(id_right.name, sil?.FirstOrDefault(), get_location(id_right), node_types); - switch (dn.general_node_type) - { - /*case general_node_type.constant_defenition: - { - constant_definition_node cdn=(constant_definition_node)dn; - return cdn.const_value; - }*/ - case general_node_type.variable_node: - { - return create_class_field_reference(en, dn, id_right); - } - case general_node_type.function_node: - { - if (dn.semantic_node_type == semantic_node_type.indefinite_definition_node) - { - return new indefinite_reference(dn as indefinite_definition_node, get_location(id_right)); - } - if (expected_delegate && en != null) - { - function_node tmp_fn = null; - bool has_empty_methods = false; - bool only_extension_methods = true; - if (sil != null) - { - foreach (SymbolInfo tmp_si in sil) - { - tmp_fn = tmp_si.sym_info as function_node; - if (tmp_fn != null) - { - if (!tmp_fn.is_extension_method) - only_extension_methods = false; - else - { - if (tmp_fn.parameters.Count == 1 || tmp_fn.parameters.Count == 2 && (tmp_fn.parameters[1].is_params || tmp_fn.parameters[1].default_value != null)) - has_empty_methods = true; - } - } - } - } - if (has_empty_methods && only_extension_methods) - expected_delegate = false; - } - if (expected_delegate) - { - return make_delegate_wrapper(en, sil, get_location(id_right), false); - } - else - { - function_node tmp_fn = null; - expressions_list pars = new expressions_list(); - if (en != null) - if(sil != null) - foreach(SymbolInfo tmp_si in sil) - { - tmp_fn = tmp_si.sym_info as function_node; - if (tmp_fn != null && tmp_fn.is_extension_method && - (tmp_fn.parameters.Count == 1 || tmp_fn.parameters.Count == 2 && (tmp_fn.parameters[1].is_params || tmp_fn.parameters[1].default_value != null))) - { - pars.AddElement(en); - break; - } - } - function_node fn = convertion_data_and_alghoritms.select_function(pars, sil, get_location(id_right)); - if (!fn.is_extension_method && fn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - return create_not_static_method_call(fn, en, get_location(id_right), false); - else - return create_static_method_call_with_params(fn, get_location(id_right), fn.return_value_type, false, pars); - } - } - case general_node_type.property_node: - { - property_node pn = (property_node)dn; - if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - AddError(new CanNotReferenceToStaticPropertyWithExpression(pn, get_location(id_right), pn.comprehensive_type)); - } - function_node fn = pn.get_function; - if (fn == null) - { - AddError(new ThisPropertyCanNotBeReaded(pn, get_location(id_right))); - } - location lloc = get_location(id_right); - check_property_no_params(pn, lloc); - return create_not_static_method_call(fn, en, lloc, false); - } - case general_node_type.constant_definition: - { - //throw new ConstMemberCannotBeAccessedWithAnInstanceReference((class_constant_definition)dn, get_location(id_right)); - return ((constant_definition_node)dn).const_value.get_constant_copy(get_location(id_right)); - } - case general_node_type.event_node: - { - if (dn.semantic_node_type == semantic_node_type.compiled_event) - { - compiled_event ce = (compiled_event)dn; - if (ce.is_static) - { - //throw new NonStaticAndStaticEvevnt(); - } - nonstatic_event_reference ser = new nonstatic_event_reference(en, ce, get_location(id_right)); - return ser; - } - else if (dn.semantic_node_type == semantic_node_type.common_event) - { - common_event ce = (common_event)dn; - if (ce.is_static) - { - //throw new NonStaticAndStaticEvevnt(); - } - nonstatic_event_reference ser = new nonstatic_event_reference(en, ce, get_location(id_right)); - return ser; - } - break; - } - } - throw new CompilerInternalError("Invalid class member"); - } - - private addressed_expression address_expression_reciving(SyntaxTree.ident id_right, SymbolInfo si, - expression_node en) - { - if (si != null && si.sym_info != null && - si.sym_info.semantic_node_type == semantic_node_type.indefinite_definition_node) - { - return new indefinite_reference(si.sym_info as indefinite_definition_node, get_location(id_right)); - } - definition_node dn = null; - if (!internal_is_assign) - dn = context.check_name_node_type(id_right.name, si, get_location(id_right), - general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node); - else - dn = context.check_name_node_type(id_right.name, si, get_location(id_right), - general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node, general_node_type.constant_definition); - if (dn.general_node_type == general_node_type.constant_definition) - { - AddError(get_location(id_right), "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT"); - } - switch (dn.general_node_type) - { - case general_node_type.variable_node: - { - return create_class_field_reference(en, dn, id_right); - } - case general_node_type.property_node: - { - property_node pn = (property_node)dn; - if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - AddError(new CanNotReferenceToStaticPropertyWithExpression(pn, get_location(id_right), pn.comprehensive_type)); - } - try_convert_typed_expression_to_function_call(ref en); - non_static_property_reference pr = new non_static_property_reference(pn, en, get_location(id_right)); - return pr; - } - case general_node_type.event_node: - { - if (dn.semantic_node_type == semantic_node_type.compiled_event) - { - compiled_event ce = (compiled_event)dn; - if (ce.is_static) - { - //throw new NonStaticAndStaticEvevnt(); - } - nonstatic_event_reference ser = new nonstatic_event_reference(en, ce, get_location(id_right)); - return ser; - } - else if (dn.semantic_node_type == semantic_node_type.common_event) - { - common_event ce = (common_event)dn; - if (ce.is_static) - { - //throw new NonStaticAndStaticEvevnt(); - } - nonstatic_event_reference ser = new nonstatic_event_reference(en, ce, get_location(id_right)); - return ser; - } - break; - } - default : return null; - } - throw new CompilerInternalError("Undefined expression to address reciving"); - } - - private bool has_property(ref List sil) - { - int si_index = 0; - if (sil != null) - { - while (si_index < sil.Count()) - { - if (sil[si_index].sym_info is compiled_property_node || sil[si_index].sym_info is common_property_node) - { - sil.RemoveRange(0, si_index); - return true; - } - ++si_index; - } - } - return false; - } - - private void dot_node_as_expression_dot_template_ident(expression_node en, SyntaxTree.ident_with_templateparams template_id_right, motivation mot, addressed_value syntax_node) - { - SyntaxTree.ident id_right = template_id_right.name as ident; - if (en is typed_expression) - try_convert_typed_expression_to_function_call(ref en); - List sil = en.type.find_in_type(id_right.name, context.CurrentScope); - if (sil == null) - { - AddError(new MemberIsNotDeclaredInType(id_right, get_location(id_right), en.type)); - } - - try_convert_typed_expression_to_function_call(ref en); - - switch (mot) - { - case motivation.address_receiving: - { - return_addressed_value(address_expression_reciving(id_right, sil?.FirstOrDefault(), en)); - return; - } - case motivation.expression_evaluation: - { - if (can_convert_to_method_call(ref sil)) - { - //dot_node dnode = new dot_node(syntax_node, template_id_right); - template_id_right.name = new dot_node(syntax_node, id_right); - method_call mc = new method_call(template_id_right, new expression_list()); - mc.visit(this); - return; - } - return_value(expression_value_reciving(id_right, sil, en, true)); - return; - } - case motivation.semantic_node_reciving: - { - if (sil.FirstOrDefault().sym_info is function_node && (sil.FirstOrDefault().sym_info as function_node).is_extension_method) - has_property(ref sil); - return_semantic_value(expression_value_reciving(id_right, sil, en, true)); - return; - } - } - throw new CompilerInternalError("Invalid motivation."); - } - - private void dot_node_as_expression_dot_ident(expression_node en, SyntaxTree.ident id_right, motivation mot, addressed_value syntax_node) - { - if (en is typed_expression) - try_convert_typed_expression_to_function_call(ref en); - if (en is typed_expression) - { - AddError(new MemberIsNotDeclaredInType(id_right, get_location(id_right), en.type)); - } - List sil = en.type.find_in_type(id_right.name, context.CurrentScope); - if (en.type.IsEnum && sil != null && sil[0].sym_info is class_constant_definition) // l.A - { - AddError(get_location(id_right), "ACCESS_TO_ENUM_CONST_THROUGH_OBJECT"); - } - if (sil == null) - { - AddError(new MemberIsNotDeclaredInType(id_right, get_location(id_right), en.type)); - } - - try_convert_typed_expression_to_function_call(ref en); - switch (mot) - { - case motivation.address_receiving: - { - return_addressed_value(address_expression_reciving(id_right, sil?.FirstOrDefault(), en)); - return; - } - case motivation.expression_evaluation: - { - if (can_convert_to_method_call(ref sil)) - { - dot_node dnode = new dot_node(syntax_node, id_right); - method_call mc = new method_call(dnode, new expression_list()); - mc.visit(this); - return; - } - return_value(expression_value_reciving(id_right, sil, en, true)); - return; - } - case motivation.semantic_node_reciving: - { - if (sil.FirstOrDefault().sym_info is function_node && (sil.FirstOrDefault().sym_info as function_node).is_extension_method) - has_property(ref sil); - return_semantic_value(expression_value_reciving(id_right, sil, en, true)); - return; - } - } - throw new CompilerInternalError("Invalid motivation."); - } - - private void dot_node_as_dot_node_dot_ident(SyntaxTree.dot_node left_dot, SyntaxTree.ident id_right, - motivation mot) - { - semantic_node sn = convert_semantic_strong(left_dot); - switch (sn.general_node_type) - { - case general_node_type.expression: - { - expression_node en = (expression_node)sn; - dot_node_as_expression_dot_ident(en, id_right, mot, left_dot); - return; - } - case general_node_type.namespace_node: - { - namespace_node nn = (namespace_node)sn; - dot_node_as_namespace_ident(nn, id_right, mot); - return; - } - case general_node_type.type_node: - { - type_node tn = (type_node)sn; - dot_node_as_type_ident(tn, id_right, mot); - return; - } - case general_node_type.unit_node: - { - throw new CompilerInternalError("Not supported"); - } - } - throw new CompilerInternalError("Invalid left dot node kind"); - } - - private void dot_node_as_dot_node_dot_template_ident(SyntaxTree.dot_node left_dot, SyntaxTree.ident_with_templateparams template_id_right, - motivation mot) - { - semantic_node sn = convert_semantic_strong(left_dot); - ident id_right = template_id_right.name as ident; - switch (sn.general_node_type) - { - case general_node_type.expression: - { - expression_node en = (expression_node)sn; - dot_node_as_expression_dot_template_ident(en, template_id_right, mot, left_dot); - return; - } - case general_node_type.namespace_node: - { - namespace_node nn = (namespace_node)sn; - dot_node_as_namespace_ident(nn, id_right, mot); - return; - } - case general_node_type.type_node: - { - type_node tn = (type_node)sn; - dot_node_as_type_ident(tn, id_right, mot); - return; - } - case general_node_type.unit_node: - { - throw new CompilerInternalError("Not supported"); - } - } - throw new CompilerInternalError("Invalid left dot node kind"); - } - - private bool can_convert_to_method_call(ref List sil) - { - List tmp_list = new List(sil); - foreach (SymbolInfo tmp_si in tmp_list) - { - if (tmp_si.sym_info is function_node && !(tmp_si.sym_info as function_node).is_extension_method && (tmp_si.sym_info as function_node).polymorphic_state != SemanticTree.polymorphic_state.ps_static - && !(tmp_si.sym_info is common_method_node && (tmp_si.sym_info as common_method_node).is_constructor) && (tmp_si.sym_info as function_node).return_value_type != null - && !(tmp_si.sym_info is compiled_constructor_node)) - return false; - } - foreach (SymbolInfo tmp_si in tmp_list) - { - if (tmp_si.sym_info is function_node && (tmp_si.sym_info as function_node).is_extension_method && !has_property(ref sil) - || tmp_si.sym_info is common_method_node && (tmp_si.sym_info as common_method_node).is_constructor - || tmp_si.sym_info is compiled_constructor_node) - return true; - } - return false; - } - - public override void visit(SyntaxTree.dot_node _dot_node) - { - var mot = motivation_keeper.motivation; - - SyntaxTree.ident id_left = _dot_node.left as SyntaxTree.ident; - SyntaxTree.ident id_right = _dot_node.right as SyntaxTree.ident; - if (_dot_node.right is ident_with_templateparams) - id_right = (_dot_node.right as ident_with_templateparams).name as ident; - - // SSM 18.08.16 - пробуем обработать захват enn.ii в yieldах где enn - поле класса и нуждается в переименовании - // Так же ниже делает lroman - if (_dot_node.left is yield_unknown_ident) - { - var yui = (yield_unknown_ident)_dot_node.left; - var av = ProcessUnknownIdent(yui); - var dn = new dot_node(av, _dot_node.right,yui.source_context); - visit(dn); - return; - } - - //lroman - if (_dot_node.left is closure_substituting_node) - { - var left = (closure_substituting_node)_dot_node.left; - var dotNodeToVisit = new dot_node(left.substitution, _dot_node.right); // Подменить dot_node в этот момент на этапе семантики - dotNodeToVisit.Parent = _dot_node.Parent; // SSM 01.06.19 - visit(dotNodeToVisit); - return; - } - motivation_keeper.reset(); // SSM перенес сюда сверху - bug fix #263 - - if (id_left != null) - { - if (_dot_node.right is ident_with_templateparams) - { - dot_node_as_ident_dot_template_ident(id_left, _dot_node.right as ident_with_templateparams, mot); - return; - } - if (id_left.name != null && id_left.name.IndexOf('.') != -1) - { - var arr = id_left.name.Split('.'); - var dotNodeToVisit = new dot_node(new ident(id_left.name.Substring(0, id_left.name.LastIndexOf('.')), id_left.source_context), new ident(arr[arr.Length-1],id_left.source_context)); - - visit(new dot_node(dotNodeToVisit, id_right, _dot_node.source_context)); - return; - } - if (id_left is inherited_ident) - inherited_ident_processing = true; - dot_node_as_ident_dot_ident(id_left, id_right, mot); - inherited_ident_processing = false; - return; - } - else - { - SyntaxTree.ident_with_templateparams iwt = _dot_node.left as SyntaxTree.ident_with_templateparams; - if (iwt != null) - { - var ret_node = ret.visit((SyntaxTree.syntax_tree_node)iwt); - if (ret_node is type_node) - { - type_node tn = ret.visit((SyntaxTree.syntax_tree_node)iwt) as type_node; - dot_node_as_type_ident(tn, id_right, mot); - return; - } - } - SyntaxTree.dot_node left_dot = _dot_node.left as SyntaxTree.dot_node; - if (left_dot != null) - { - if (_dot_node.right is ident_with_templateparams) - { - dot_node_as_dot_node_dot_template_ident(left_dot, _dot_node.right as ident_with_templateparams, mot); - return; - } - dot_node_as_dot_node_dot_ident(left_dot, id_right, mot); - return; - } - expression_node en = convert_strong(_dot_node.left); - if (_dot_node.right is ident_with_templateparams) - { - dot_node_as_expression_dot_template_ident(en, _dot_node.right as ident_with_templateparams, mot, _dot_node.left); - return; - } - dot_node_as_expression_dot_ident(en, id_right, mot, _dot_node.left); - return; - } - } - - private SyntaxTree.ident ConvertOperatorNameToIdent(SyntaxTree.ident opname) - { - if (opname is SyntaxTree.operator_name_ident) - { - SyntaxTree.ident id = new SyntaxTree.ident(name_reflector.get_name((opname as SyntaxTree.operator_name_ident).operator_type)); - id.source_context = opname.source_context; - return id; - } - return opname; - } - - - - private void visit_method_name(SyntaxTree.method_name _method_name) - { - convertion_data_and_alghoritms.check_node_parser_error(_method_name); - convertion_data_and_alghoritms.check_node_parser_error(_method_name.meth_name); - common_type_node tp = null; - definition_node def_temp = null; - SyntaxTree.template_type_name ttn = null; - bool is_operator = _method_name.meth_name is SyntaxTree.operator_name_ident; - if (is_operator && context.converted_type != null && context.converted_type.IsInterface) - AddError(get_location(_method_name), "OPERATORS_IN_INTERFACES_NOT_ALLOWED"); - SyntaxTree.Operators op = PascalABCCompiler.SyntaxTree.Operators.Undefined; - if(is_operator) - op=(_method_name.meth_name as SyntaxTree.operator_name_ident).operator_type; - _method_name.meth_name = ConvertOperatorNameToIdent(_method_name.meth_name); - bool explicit_impl = false; - if ((context.converting_block() != block_type.namespace_block) && (_method_name.class_name != null)) - { - explicit_impl = true; - } - if (is_operator && op==SyntaxTree.Operators.AddressOf && SemanticRules.AddressOfOperatorNonOverloaded) - { - AddError(get_location(_method_name.meth_name), "NOT_OVERLOADED_OPERATOR"); - } - bool common_extension_meth = false; - if (_method_name.class_name != null) - { - convertion_data_and_alghoritms.check_node_parser_error(_method_name.class_name); - location loc_type_name = get_location(_method_name.class_name); - ttn = _method_name.class_name as SyntaxTree.template_type_name; - int num_template_args = 0; - if (ttn != null) - { - num_template_args = ttn.template_args.idents.Count; - } - common_type_node current_conv_type = context.converted_type; - def_temp = context.enter_in_type_method(_method_name, _method_name.class_name.name, loc_type_name, num_template_args); - if (explicit_impl) - { - context.converted_type = current_conv_type; - if (def_temp is type_node && (def_temp as type_node).IsInterface) - { - context.converted_explicit_interface_type = def_temp as type_node; - List sil = context.converted_explicit_interface_type.find_in_type(_method_name.meth_name.name); - if (sil == null) - AddError(new UndefinedNameReference(_method_name.meth_name.name, get_location(_method_name.meth_name))); - } - else - AddError(new OnlyProcedureNameAllowedInClassFunctionDefinition(_method_name.class_name.name, - get_location(_method_name.class_name))); - } - tp = def_temp as common_type_node; - template_class tc = def_temp as template_class; - //SyntaxTree.template_type_name ttn = _method_name.class_name as SyntaxTree.template_type_name; - if (ttn != null && !(def_temp is compiled_type_node)) - { - int count; - if (tp == null) - { - if (tc != null) - { - if (tc.is_synonym) - { - AddError(loc_type_name, "CAN_NOT_DEFINE_METHOD_OF_TEMPLATE_TYPE_SYNONYM"); - } - SyntaxTree.class_definition cl_def = tc.type_dec.type_def as SyntaxTree.class_definition; - count = cl_def.template_args.idents.Count; - if (count != ttn.template_args.idents.Count) - { - AddError(get_location(ttn), "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", tc.name, count); - } - for (int i = 0; i < count; ++i) - { - if (string.Compare(cl_def.template_args.idents[i].name, ttn.template_args.idents[i].name, true) != 0) - { - AddError(get_location(ttn.template_args.idents[i]), "PARAMETER_{0}_MUST_BE_NAMED_{1}", i + 1, cl_def.template_args.idents[i].name); - } - } - _method_name.class_name = new SyntaxTree.ident(ttn.name); - _method_name.class_name.source_context = ttn.source_context; - return; - } - AddError(get_location(ttn), "COULD_NOT_DEFINE_GENERIC_FUNCTION_OF_COMPILED_TYPE"); - } - if (tp.generic_params == null) - { - AddError(get_location(ttn), "{0}_IS_NOT_TEMPLATE_CLASS", tp.PrintableName); - } - count = tp.generic_params.Count; - if (count != ttn.template_args.idents.Count) - { - AddError(get_location(ttn), "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", tp.PrintableName, count); - } - for (int i = 0; i < count; ++i) - { - if (string.Compare(tp.generic_params[i].name, ttn.template_args.idents[i].name, true) != 0) - { - AddError(get_location(ttn.template_args.idents[i]), "PARAMETER_{0}_MUST_BE_NAMED_{1}", i + 1, tp.generic_params[i].name); - } - } - } - else - { - if (tp != null && tp.is_generic_type_definition) - { - AddError(get_location(_method_name.class_name), "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", tp.PrintableName, tp.generic_params.Count); - } - if (tc != null) - { - var td = tc.type_dec.type_def as SyntaxTree.class_definition; - var cnt = 0; - if (td != null) - cnt = td.template_args.idents.Count; - var td1 = tc.type_dec.type_def as SyntaxTree.template_type_reference; - if (td1 != null) - cnt = td1.params_list.Count; - AddError(get_location(_method_name.class_name), "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", tc.name, cnt); - } - } - //(ds)проверяем на компилированный тип - if (!(def_temp is compiled_type_node)) - { - //(ssyy) проверяем на шаблон - if (tp == null) - { - return; - } - if (tp is compiled_generic_instance_type_node || tp is common_generic_instance_type_node) - AddError(get_location(_method_name), "EXTENSION_METHOD_FOR_GENERIC_INSTANCES"); - List sil = tp.scope.FindOnlyInScope(_method_name.meth_name.name); - - if (tp.original_template == null && ((sil == null && this._compiled_unit.namespaces.IndexOf(tp.comprehensive_namespace) == -1) || (sil != null && this._compiled_unit.namespaces.IndexOf(tp.comprehensive_namespace) == -1)) && !explicit_impl) - { - - if (def_temp is common_type_node) - { - common_extension_meth = true; - common_type_node ctn = def_temp as common_type_node; - if (ctn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.array_wrapper || - ctn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.set_type || - ctn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.base_set_type || - ctn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.binary_file || - ctn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.text_file || - ctn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.typed_file) - AddError(get_location(_method_name), "NO_METHOD_{0}_IN_CLASS_{1}", _method_name.meth_name.name, tp.PrintableName); - } - else - AddError(get_location(_method_name), "NO_METHOD_{0}_IN_CLASS_{1}", _method_name.meth_name.name, tp.PrintableName); - } - } - else if (def_temp as compiled_type_node == SystemLibrary.SystemLibrary.void_type) - AddError(get_location(_method_name.class_name), "VOID_NOT_VALID"); - } - else - { - if (is_operator && context.converted_type == null && context.converted_template_type == null && !(current_function_header != null && current_function_header.proc_attributes != null && has_extensionmethod_attr(current_function_header.proc_attributes.proc_attributes)) /*&& !(current_function_header != null && current_function_header.template_args != null && current_function_header.template_args.idents.Count > 0)*/) - { - AddError(get_location(_method_name), "OVERLOADED_OPERATOR_MUST_BE_STATIC_FUNCTION"); - } - - } - convertion_data_and_alghoritms.check_node_parser_error(_method_name.meth_name); - location loc_name = get_location(_method_name.meth_name); - context.extension_method = common_extension_meth; - if (LambdaHelper.IsLambdaName(_method_name.meth_name) && lambdaProcessingState != LambdaProcessingState.ClosuresProcessingVisitGeneratedClassesPhase) //lroman// - { - if (lambdaProcessingState == LambdaProcessingState.None && - context.converting_block() == block_type.namespace_block) - { - context.create_function(_method_name.meth_name.name, loc_name); - } - else - { - var addSymbol = (lambdaProcessingState == LambdaProcessingState.TypeInferencePhase && - LambdaHelper.IsAuxiliaryLambdaName(_method_name.meth_name)) || lambdaProcessingState == LambdaProcessingState.FinishPhase; - context.create_lambda_function(_method_name.meth_name.name, loc_name, addSymbol, context.CurrentScope); - } - } - else - { - if (current_function_header != null && current_function_header.proc_attributes != null && has_extensionmethod_attr(current_function_header.proc_attributes.proc_attributes)) - context.create_function(_method_name.meth_name.name, loc_name, false); - else - { - if (!explicit_impl) - context.create_function(_method_name.meth_name.name, loc_name); - else - context.create_function(context.converted_explicit_interface_type.BaseFullName+"."+_method_name.meth_name.name, loc_name); - } - } - context.extension_method = false; - context.top_function.IsOperator = is_operator; - if (ttn != null && def_temp is compiled_type_node) - { - if (!explicit_impl) - visit_generic_params(context.top_function, ttn.template_args.idents); - else - { - List instance_params = new List(); - foreach (ident id in ttn.template_args.idents) - { - SymbolInfo si = context.find_first(id.name); - if (si == null) - AddError(new UndefinedNameReference(id.name, get_location(id))); - if (!(si.sym_info is type_node)) - AddError(new ExpectedType(get_location(id))); - instance_params.Add(si.sym_info as type_node); - } - if (!context.converted_explicit_interface_type.IsInterface) - AddError(get_location(ttn), "INTERFACE_EXPECTED"); - type_node inst_tn = context.converted_explicit_interface_type.get_instance(instance_params); - bool found = false; - if (context.converted_type.ImplementingInterfaces.Count > 0) - { - foreach (type_node interf in context.converted_type.ImplementingInterfaces) - { - if (interf == inst_tn) - { - found = true; - break; - } - } - } - if (!found) - AddError(get_location(ttn),"CLASS_NOT_IMPLEMENT_THIS_INTERFACE"); - } - } - //context.top_function.IsOperator = _method_name.meth_name is SyntaxTree.operator_name_ident; - - } - - public override void visit(SyntaxTree.method_name _method_name) - { - visit_method_name(_method_name); - } - - private void is_case_variant_intersection_with_another(switch_node sn, int_const_node defined_const, location curloc) - { - foreach (case_variant_node cv in sn.case_variants) - { - foreach (int_const_node cn in cv.case_constants) - { - if (cn.constant_value == defined_const.constant_value) - { - AddError(curloc, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_ANOTHER"); - } - } - foreach (case_range_node cr in cv.case_ranges) - { - if ((defined_const.constant_value <= cr.high_bound.constant_value) && - (defined_const.constant_value >= cr.lower_bound.constant_value)) - { - AddError(curloc, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_DIAPASON"); - } - } - } - } - - private void is_case_range_intersection_with_another(switch_node sn, case_range_node defined_range, location curloc) - { - foreach (case_variant_node cv in sn.case_variants) - { - foreach (int_const_node icn in cv.case_constants) - { - if ((icn.constant_value >= defined_range.lower_bound.constant_value) && - (icn.constant_value <= defined_range.high_bound.constant_value)) - { - AddError(curloc, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_DIAPASON"); - } - } - foreach (case_range_node cr in cv.case_ranges) - { - if ((cr.lower_bound.constant_value <= defined_range.high_bound.constant_value) && - (cr.lower_bound.constant_value >= defined_range.lower_bound.constant_value)) - { - AddError(curloc, "CASE_DIAPASON_VARIANT_INTERSECTION"); - } - if ((cr.high_bound.constant_value <= defined_range.high_bound.constant_value) && - (cr.high_bound.constant_value >= defined_range.lower_bound.constant_value)) - { - AddError(curloc, "CASE_DIAPASON_VARIANT_INTERSECTION"); - } - } - } - } - - private string_const_node convert_string_const_to_switch(expression_node switch_expr, location loc) - { - if (switch_expr is string_const_node) - return switch_expr as string_const_node; - string_const_node scn = null; - if (switch_expr is static_compiled_variable_reference && (switch_expr as static_compiled_variable_reference).var.compiled_field.IsLiteral) - scn = new string_const_node((string)(switch_expr as static_compiled_variable_reference).var.compiled_field.GetRawConstantValue(), loc); - if (scn == null) - { - AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); - } - return scn; - } - - private long_const_node convert_long_const_to_switch(expression_node switch_expr, location loc) - { - convertion_data_and_alghoritms.convert_type(switch_expr, SystemLibrary.SystemLibrary.int64_type, loc); - if (switch_expr is long_const_node) - return switch_expr as long_const_node; - //switch_expr = convertion_data_and_alghoritms.create_simple_function_call(oti.value_to_int, - // loc, switch_expr); - long_const_node icn = null;//switch_expr as constant_node; - - if (switch_expr is byte_const_node) - icn = new long_const_node((switch_expr as byte_const_node).constant_value, loc); - else if (switch_expr is sbyte_const_node) - icn = new long_const_node((long)((switch_expr as sbyte_const_node).constant_value), loc); - else if (switch_expr is short_const_node) - icn = new long_const_node((long)((switch_expr as short_const_node).constant_value), loc); - else if (switch_expr is ushort_const_node) - icn = new long_const_node((long)((switch_expr as ushort_const_node).constant_value), loc); - else if (switch_expr is uint_const_node) - icn = new long_const_node((long)((switch_expr as uint_const_node).constant_value),loc); - else if (switch_expr is int_const_node) - icn = new long_const_node((long)((switch_expr as int_const_node).constant_value),loc); - else if (switch_expr is ulong_const_node) - icn = new long_const_node((long)((switch_expr as ulong_const_node).constant_value), loc); - else if (switch_expr is enum_const_node) - icn = new long_const_node((switch_expr as enum_const_node).constant_value, loc); - else if (switch_expr is static_compiled_variable_reference && (switch_expr as static_compiled_variable_reference).var.compiled_field.IsLiteral) - icn = new long_const_node((long)(switch_expr as static_compiled_variable_reference).var.compiled_field.GetRawConstantValue(), loc); - //учти здесь модет быть и long! - //-DarkStar Add - if (icn == null) - { - AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); - } - return icn; - } - - private ulong_const_node convert_ulong_const_to_switch(expression_node switch_expr, location loc) - { - convertion_data_and_alghoritms.convert_type(switch_expr, SystemLibrary.SystemLibrary.uint64_type, loc); - if (switch_expr is ulong_const_node) - return switch_expr as ulong_const_node; - //switch_expr = convertion_data_and_alghoritms.create_simple_function_call(oti.value_to_int, - // loc, switch_expr); - ulong_const_node icn = null;//switch_expr as constant_node; - - if (switch_expr is byte_const_node) - icn = new ulong_const_node((switch_expr as byte_const_node).constant_value, loc); - else if (switch_expr is sbyte_const_node) - icn = new ulong_const_node((ulong)((switch_expr as sbyte_const_node).constant_value), loc); - else if (switch_expr is short_const_node) - icn = new ulong_const_node((ulong)((switch_expr as short_const_node).constant_value), loc); - else if (switch_expr is ushort_const_node) - icn = new ulong_const_node((ulong)((switch_expr as ushort_const_node).constant_value), loc); - else if (switch_expr is int_const_node) - icn = new ulong_const_node((ulong)((switch_expr as int_const_node).constant_value),loc); - else if (switch_expr is uint_const_node) - icn = new ulong_const_node((ulong)((switch_expr as uint_const_node).constant_value), loc); - else if (switch_expr is long_const_node) - icn = new ulong_const_node((ulong)((switch_expr as long_const_node).constant_value),loc); - else if (switch_expr is char_const_node) - icn = new ulong_const_node((ulong)((switch_expr as char_const_node).constant_value), loc); - else if (switch_expr is enum_const_node) - icn = new ulong_const_node((ulong)((switch_expr as enum_const_node).constant_value), loc); - else if (switch_expr is static_compiled_variable_reference && (switch_expr as static_compiled_variable_reference).var.compiled_field.IsLiteral) - icn = new ulong_const_node((ulong)(switch_expr as static_compiled_variable_reference).var.compiled_field.GetRawConstantValue(), loc); - //учти здесь модет быть и long! - //-DarkStar Add - if (icn == null) - { - AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); - } - return icn; - } - - private int_const_node convert_const_to_switch(expression_node switch_expr, - ordinal_type_interface oti, type_node case_expr_type, location loc) - { - convertion_data_and_alghoritms.convert_type(switch_expr, case_expr_type, loc); - if (switch_expr is int_const_node) - return switch_expr as int_const_node; - //switch_expr = convertion_data_and_alghoritms.create_simple_function_call(oti.value_to_int, - // loc, switch_expr); - int_const_node icn = null;//switch_expr as constant_node; - - if (switch_expr is byte_const_node) - icn = new int_const_node((switch_expr as byte_const_node).constant_value, loc); - else if (switch_expr is sbyte_const_node) - icn = new int_const_node(Convert.ToInt32((switch_expr as sbyte_const_node).constant_value), loc); - else if (switch_expr is short_const_node) - icn = new int_const_node(Convert.ToInt32((switch_expr as short_const_node).constant_value), loc); - else if (switch_expr is ushort_const_node) - icn = new int_const_node(Convert.ToInt32((switch_expr as ushort_const_node).constant_value), loc); - else if (switch_expr is bool_const_node) - icn = new int_const_node(Convert.ToInt32((switch_expr as bool_const_node).constant_value), loc); - else if (switch_expr is char_const_node) - icn = new int_const_node(Convert.ToInt32((switch_expr as char_const_node).constant_value), loc); - else if (switch_expr is enum_const_node) - icn = new int_const_node((switch_expr as enum_const_node).constant_value, loc); - else if (switch_expr is static_compiled_variable_reference && (switch_expr as static_compiled_variable_reference).var.compiled_field.IsLiteral) - icn = new int_const_node((int)(switch_expr as static_compiled_variable_reference).var.compiled_field.GetRawConstantValue(), loc); - //учти здесь модет быть и long! - //-DarkStar Add - if (icn == null) - { - AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); - } - return icn; - } - - //TODO: Добавить приведение типов. - public override void visit(SyntaxTree.case_node _case_node) - { - convertion_data_and_alghoritms.check_node_parser_error(_case_node); - switch_node sn = new switch_node(get_location(_case_node)); - expression_node en = convert_strong(_case_node.param); - if (en is typed_expression) en = convert_typed_expression_to_function_call(en as typed_expression); - type_node case_expr_type = en.type; - - internal_interface ii = en.type.get_internal_interface(internal_interface_kind.ordinal_interface); - if (ii == null) - { - // Попытка воспользоваться неявным преобразованием - if (convertion_data_and_alghoritms.can_convert_type(en, SystemLibrary.SystemLibrary.integer_type)) - en = convertion_data_and_alghoritms.convert_type(en, SystemLibrary.SystemLibrary.integer_type); - ii = en.type.get_internal_interface(internal_interface_kind.ordinal_interface); - if (ii == null) - if (convertion_data_and_alghoritms.can_convert_type(en, SystemLibrary.SystemLibrary.string_type)) - en = convertion_data_and_alghoritms.convert_type(en, SystemLibrary.SystemLibrary.string_type); - } - if (ii == null && en.type != SystemLibrary.SystemLibrary.string_type) - { - AddError(new OrdinalOrStringTypeExpected(en.location)); - } - if (ii != null && en.type != SystemLibrary.SystemLibrary.int64_type && en.type != SystemLibrary.SystemLibrary.uint64_type) - { - ordinal_type_interface oti = (ordinal_type_interface)ii; - en = convertion_data_and_alghoritms.create_simple_function_call(oti.value_to_int, en.location, en); - - sn.condition = en; - - foreach (SyntaxTree.case_variant cv in _case_node.conditions.variants) - { - convertion_data_and_alghoritms.check_node_parser_error(cv); - case_variant_node sem_cv = new case_variant_node(get_location(cv)); - sn.case_variants.AddElement(sem_cv); - foreach (SyntaxTree.expression expr in cv.conditions.expressions) - { - convertion_data_and_alghoritms.check_node_parser_error(expr); - SyntaxTree.diapason_expr diap = expr as SyntaxTree.diapason_expr; - if (diap == null) - { - expression_node cn = convert_strong(expr); - int_const_node icn = convert_const_to_switch(cn, oti, case_expr_type, get_location(expr)); - is_case_variant_intersection_with_another(sn, icn, get_location(expr)); - sem_cv.case_constants.AddElement(icn); - } - else - { - convertion_data_and_alghoritms.check_node_parser_error(diap.left); - expression_node left = convert_strong(diap.left); - int_const_node icn_left = convert_const_to_switch(left, oti, case_expr_type, get_location(diap.left)); - - convertion_data_and_alghoritms.check_node_parser_error(diap.right); - expression_node right = convert_strong(diap.right); - int_const_node icn_right = convert_const_to_switch(right, oti, case_expr_type, get_location(diap.right)); - //ssyy - if (icn_left.constant_value > icn_right.constant_value) - { - AddError(get_location(diap.right), "LEFT_RANGE_GREATER_THEN_RIGHT"); - } - //\ssyy - case_range_node crn = new case_range_node(icn_left, icn_right, get_location(diap)); - is_case_range_intersection_with_another(sn, crn, get_location(expr)); - sem_cv.case_ranges.AddElement(crn); - } - } - context.enter_code_block_with_bind(); - CheckToEmbeddedStatementCannotBeADeclaration(cv.exec_if_true); - statement_node stmn = convert_strong(cv.exec_if_true); - context.leave_code_block(); - sem_cv.case_statement = stmn; - //sn.case_variants.AddElement(sem_cv); - } - context.enter_code_block_with_bind(); - statement_node else_statement = convert_weak(_case_node.else_statement); - context.leave_code_block(); - sn.default_statement = else_statement; - return_value(sn); - } - else if (en.type == SystemLibrary.SystemLibrary.string_type) - { - if_node main_ifn = null; - if_node ifn = null; - compiled_function_node str_eq_meth = SystemLibrary.SystemLibrary.string_type.find_first_in_type("=").sym_info as compiled_function_node; - Dictionary case_constants = new Dictionary(); - foreach (SyntaxTree.case_variant cv in _case_node.conditions.variants) - { - convertion_data_and_alghoritms.check_node_parser_error(cv); - location loc = get_location(cv); - expression_node eq_node = null; - List eq_calls = new List(); - foreach (SyntaxTree.expression expr in cv.conditions.expressions) - { - expression_node cn = convert_strong(expr); - if (cn.type == SystemLibrary.SystemLibrary.char_type) - cn = convertion_data_and_alghoritms.convert_type(cn, SystemLibrary.SystemLibrary.string_type); - if (cn.type != SystemLibrary.SystemLibrary.string_type) - AddError(new CanNotConvertTypes(cn, cn.type, SystemLibrary.SystemLibrary.string_type, cn.location)); - string_const_node scn = convert_string_const_to_switch(cn, cn.location); - if (!case_constants.ContainsKey(scn.constant_value)) - case_constants.Add(scn.constant_value, scn.constant_value); - else - AddError(cn.location, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_ANOTHER"); - compiled_static_method_call eq_call = new compiled_static_method_call(str_eq_meth, cn.location); - eq_call.parameters.AddElement(en); - eq_call.parameters.AddElement(cn); - eq_calls.Add(eq_call); - } - foreach (compiled_static_method_call eq_call in eq_calls) - { - if (eq_node == null) - eq_node = eq_call; - else - eq_node = new basic_function_call(SystemLibrary.SystemLibrary.bool_or as basic_function_node, null, eq_node, eq_call); - } - context.enter_code_block_with_bind(); - CheckToEmbeddedStatementCannotBeADeclaration(cv.exec_if_true); - statement_node stmn = convert_strong(cv.exec_if_true); - context.leave_code_block(); - if (ifn != null) - { - ifn.else_body = new if_node(eq_node, stmn, null, loc); - ifn = ifn.else_body as if_node; - } - else - ifn = new if_node(eq_node, stmn, null, loc); - if (main_ifn == null) - main_ifn = ifn; - } - context.enter_code_block_with_bind(); - CheckToEmbeddedStatementCannotBeADeclaration(_case_node.else_statement); - statement_node else_statement = convert_weak(_case_node.else_statement); - context.leave_code_block(); - if (ifn == null) - { - ifn = new if_node(en, new statements_list(null), null, get_location(_case_node)); - main_ifn = ifn; - } - ifn.else_body = else_statement; - return_value(main_ifn); - } - else if (en.type == SystemLibrary.SystemLibrary.int64_type) - { - if_node main_ifn = null; - if_node ifn = null; - basic_function_node int64_eq_meth = SystemLibrary.SystemLibrary.int64_type.find_first_in_type("=", true).sym_info as basic_function_node; - - Dictionary case_constants = new Dictionary(); - foreach (SyntaxTree.case_variant cv in _case_node.conditions.variants) - { - convertion_data_and_alghoritms.check_node_parser_error(cv); - location loc = get_location(cv); - expression_node eq_node = null; - List eq_calls = new List(); - foreach (SyntaxTree.expression expr in cv.conditions.expressions) - { - SyntaxTree.diapason_expr diap = expr as SyntaxTree.diapason_expr; - if (diap == null) - { - expression_node cn = convert_strong(expr); - long_const_node scn = convert_long_const_to_switch(cn, cn.location); - if (!case_constants.ContainsKey(scn.constant_value)) - case_constants.Add(scn.constant_value, scn.constant_value); - else - AddError(cn.location, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_ANOTHER"); - basic_function_call eq_call = new basic_function_call(int64_eq_meth, cn.location); - eq_call.parameters.AddElement(en); - eq_call.parameters.AddElement(scn); - eq_calls.Add(eq_call); - } - else - { - expression_node left_cn = convert_strong(diap.left); - expression_node right_cn = convert_strong(diap.right); - long_const_node left_scn = convert_long_const_to_switch(left_cn, left_cn.location); - long_const_node right_scn = convert_long_const_to_switch(right_cn, right_cn.location); - if (left_scn.constant_value > right_scn.constant_value) - { - AddError(get_location(diap.right), "LEFT_RANGE_GREATER_THEN_RIGHT"); - } - basic_function_node int64_greq_meth = SystemLibrary.SystemLibrary.int64_type.find_first_in_type(">=", true).sym_info as basic_function_node; - basic_function_node int64_leq_meth = SystemLibrary.SystemLibrary.int64_type.find_first_in_type("<=", true).sym_info as basic_function_node; - basic_function_call greq_call = new basic_function_call(int64_greq_meth, left_cn.location); - greq_call.parameters.AddElement(en); - greq_call.parameters.AddElement(left_scn); - basic_function_call leq_call = new basic_function_call(int64_leq_meth, right_cn.location); - leq_call.parameters.AddElement(en); - leq_call.parameters.AddElement(right_scn); - basic_function_node in_diap_meth = SystemLibrary.SystemLibrary.bool_type.find_first_in_type("and", true).sym_info as basic_function_node; - basic_function_call in_diap_call = new basic_function_call(in_diap_meth, left_cn.location); - in_diap_call.parameters.AddElement(greq_call); - in_diap_call.parameters.AddElement(leq_call); - eq_calls.Add(in_diap_call); - } - } - foreach (basic_function_call eq_call in eq_calls) - { - if (eq_node == null) - eq_node = eq_call; - else - eq_node = new basic_function_call(SystemLibrary.SystemLibrary.bool_or as basic_function_node, null, eq_node, eq_call); - } - context.enter_code_block_with_bind(); - CheckToEmbeddedStatementCannotBeADeclaration(cv.exec_if_true); - statement_node stmn = convert_strong(cv.exec_if_true); - context.leave_code_block(); - if (ifn != null) - { - ifn.else_body = new if_node(eq_node, stmn, null, loc); - ifn = ifn.else_body as if_node; - } - else - ifn = new if_node(eq_node, stmn, null, loc); - if (main_ifn == null) - main_ifn = ifn; - } - context.enter_code_block_with_bind(); - CheckToEmbeddedStatementCannotBeADeclaration(_case_node.else_statement); - statement_node else_statement = convert_weak(_case_node.else_statement); - context.leave_code_block(); - if (ifn == null) - { - ifn = new if_node(en, new statements_list(null), null, get_location(_case_node)); - main_ifn = ifn; - } - ifn.else_body = else_statement; - return_value(main_ifn); - } - else - { - if_node main_ifn = null; - if_node ifn = null; - basic_function_node uint64_eq_meth = SystemLibrary.SystemLibrary.uint64_type.find_first_in_type("=", true).sym_info as basic_function_node; - Dictionary case_constants = new Dictionary(); - foreach (SyntaxTree.case_variant cv in _case_node.conditions.variants) - { - convertion_data_and_alghoritms.check_node_parser_error(cv); - location loc = get_location(cv); - expression_node eq_node = null; - List eq_calls = new List(); - foreach (SyntaxTree.expression expr in cv.conditions.expressions) - { - SyntaxTree.diapason_expr diap = expr as SyntaxTree.diapason_expr; - if (diap == null) - { - expression_node cn = convert_strong(expr); - ulong_const_node scn = convert_ulong_const_to_switch(cn, cn.location); - if (!case_constants.ContainsKey(scn.constant_value)) - case_constants.Add(scn.constant_value, scn.constant_value); - else - AddError(cn.location, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_ANOTHER"); - basic_function_call eq_call = new basic_function_call(uint64_eq_meth, cn.location); - eq_call.parameters.AddElement(en); - eq_call.parameters.AddElement(scn); - eq_calls.Add(eq_call); - } - else - { - expression_node left_cn = convert_strong(diap.left); - expression_node right_cn = convert_strong(diap.right); - ulong_const_node left_scn = convert_ulong_const_to_switch(left_cn, left_cn.location); - ulong_const_node right_scn = convert_ulong_const_to_switch(right_cn, right_cn.location); - if (left_scn.constant_value > right_scn.constant_value) - { - AddError(get_location(diap.right), "LEFT_RANGE_GREATER_THEN_RIGHT"); - } - basic_function_node uint64_greq_meth = SystemLibrary.SystemLibrary.uint64_type.find_first_in_type(">=", true).sym_info as basic_function_node; - basic_function_node uint64_leq_meth = SystemLibrary.SystemLibrary.uint64_type.find_first_in_type("<=", true).sym_info as basic_function_node; - basic_function_call greq_call = new basic_function_call(uint64_greq_meth, left_cn.location); - greq_call.parameters.AddElement(en); - greq_call.parameters.AddElement(left_scn); - basic_function_call leq_call = new basic_function_call(uint64_leq_meth, right_cn.location); - leq_call.parameters.AddElement(en); - leq_call.parameters.AddElement(right_scn); - basic_function_node in_diap_meth = SystemLibrary.SystemLibrary.bool_type.find_first_in_type("and", true).sym_info as basic_function_node; - basic_function_call in_diap_call = new basic_function_call(in_diap_meth, left_cn.location); - in_diap_call.parameters.AddElement(greq_call); - in_diap_call.parameters.AddElement(leq_call); - eq_calls.Add(in_diap_call); - } - } - foreach (basic_function_call eq_call in eq_calls) - { - if (eq_node == null) - eq_node = eq_call; - else - eq_node = new basic_function_call(SystemLibrary.SystemLibrary.bool_or as basic_function_node, null, eq_node, eq_call); - } - context.enter_code_block_with_bind(); - CheckToEmbeddedStatementCannotBeADeclaration(cv.exec_if_true); - statement_node stmn = convert_strong(cv.exec_if_true); - context.leave_code_block(); - if (ifn != null) - { - ifn.else_body = new if_node(eq_node, stmn, null, loc); - ifn = ifn.else_body as if_node; - } - else - ifn = new if_node(eq_node, stmn, null, loc); - if (main_ifn == null) - main_ifn = ifn; - } - context.enter_code_block_with_bind(); - CheckToEmbeddedStatementCannotBeADeclaration(_case_node.else_statement); - statement_node else_statement = convert_weak(_case_node.else_statement); - context.leave_code_block(); - if (ifn == null) - { - ifn = new if_node(en, new statements_list(null), null, get_location(_case_node)); - main_ifn = ifn; - } - ifn.else_body = else_statement; - return_value(main_ifn); - } - } - - public override void visit(SyntaxTree.case_variant _case_variant) - { - throw new NotSupportedError(get_location(_case_variant)); - } - - public override void visit(SyntaxTree.get_address _get_address) - { - expression_node exp = convert_strong(_get_address.address_of); - if (!exp.is_addressed) - { - AddError(exp.location, "CAN_NOT_GET_ADDRESS_FROM_EXPRESSION"); - } - expression_node res = new get_addr_node(exp, get_location(_get_address)); - return_value(res); - } - - public override void visit(SyntaxTree.hex_constant _hex_constant) - { - expression_node en = null; - if (_hex_constant.val <= Int32.MaxValue && _hex_constant.val >= Int32.MinValue) - en = new int_const_node((int)_hex_constant.val, get_location(_hex_constant)); - else - en = new long_const_node(_hex_constant.val, get_location(_hex_constant)); - return_value(en); - } - - private System.Collections.Generic.List ConvertDirectives(SyntaxTree.compilation_unit cu) - { - System.Collections.Generic.List list = new System.Collections.Generic.List(); - foreach (SyntaxTree.compiler_directive sncd in cu.compiler_directives) - { - list.Add(new compiler_directive(sncd.Name.text, sncd.Directive!=null?sncd.Directive.text:"", get_location(sncd), cu.file_name)); - } - return list; - } - - //TODO: Слить как нибудь два следующих метода. - public override void visit(SyntaxTree.program_module _program_module) - { - //MikhailoMMX Инициализация OpenMP - OpenMP.InitOpenMP(_program_module.compiler_directives, this, _program_module); - //\MikhailoMMX - - string namespace_name = ""; - location loc = get_location(_program_module); - if (_program_module.program_name != null) - { - namespace_name = _program_module.program_name.prog_name.name; - loc = get_location(_program_module.program_name.prog_name); - } - - - _compiled_unit = new common_unit_node(); - - _compiled_unit.compiler_directives = ConvertDirectives(_program_module); - - - SymbolTable.Scope[] used_units = build_referenced_units(referenced_units,true); - - _compiled_unit.scope = convertion_data_and_alghoritms.symbol_table.CreateUnitInterfaceScope(used_units, namespace_name == ""? System.IO.Path.GetFileName(CurrentDocument.file_name) : namespace_name); - - common_namespace_node cnsn = context.create_namespace(namespace_name, _compiled_unit, _compiled_unit.scope, loc); - cnsn.is_main = true; - - reset_for_interface(); - - UpdateUnitDefinitionItemForUnit(_compiled_unit); - hard_node_test_and_visit(_program_module.program_block); - context.check_labels(context.converted_namespace.labels); - - // frninja 28/04/16 - режем мусорные методы хелперы yield - { - var toRemove = cnsn.functions.Where(m => m.is_yield_helper).ToArray(); - foreach (var m in toRemove) - { - cnsn.functions.remove(m); - } - } - // end frninja - - common_namespace_function_node main_function = new common_namespace_function_node(compiler_string_consts.temp_main_function_name, - null, null, cnsn, null); - main_function.function_code = context.code; - context.apply_special_local_vars(main_function); - cnsn.functions.AddElement(main_function); - - context.leave_block(); -#if DEBUG - /*var fname = "C:\\st1.txt"; - if (System.IO.File.Exists(fname)) - System.IO.File.Delete(fname); - System.IO.File.AppendAllText(fname, SymbolTable.ToString());*/ -#endif - - _compiled_unit.main_function = main_function; - } - - - private void reset_for_interface() - { - body_exists = false; - } - - private bool check_for_dll_entry_module(List directives) - { - foreach (compiler_directive cd in directives) - { - if (string.Compare(cd.name,"apptype",true)==0 && string.Compare(cd.directive,"dll",true)==0) - return true; - } - return false; - } - - - - internal bool _is_interface_part = false; - public override void visit(SyntaxTree.unit_module _unit_module) - { - //MikhailoMMX Инициализация OpenMP - OpenMP.InitOpenMP(_unit_module.compiler_directives, this, _unit_module); - //\MikhailoMMX - - //current_document=new document(_unit_module.file_name); - string namespace_name = ""; - _is_interface_part = true; - location loc = null; - if (_unit_module.unit_name != null) - { - namespace_name = _unit_module.unit_name.idunit_name.name; - loc = get_location(_unit_module.unit_name.idunit_name); - if (namespace_name.ToLower() != System.IO.Path.GetFileNameWithoutExtension(_unit_module.file_name).ToLower()) - AddError(loc, "UNIT_NAME_MUST_BE_EQUAL_UNIT_FILE_NAME"); - } - - - _compiled_unit = new common_unit_node(_unit_module.unit_name.idunit_name.name); - assign_doc_info(_compiled_unit,_unit_module.unit_name); - _compiled_unit.compiler_directives = ConvertDirectives(_unit_module); - - SymbolTable.Scope[] used_units = build_referenced_units(referenced_units,true); - - _compiled_unit.scope = convertion_data_and_alghoritms.symbol_table.CreateUnitInterfaceScope(used_units, "unit " + namespace_name); - - common_namespace_node cnsn = context.create_namespace(namespace_name, _compiled_unit, _compiled_unit.scope, loc); - - _compiled_unit.add_unit_name_to_namespace(); - - if (check_for_dll_entry_module(_compiled_unit.compiler_directives)) - { - cnsn.is_main = true; - } - UpdateUnitDefinitionItemForUnit(_compiled_unit); - reset_for_interface(); - in_interface_part = false; - if (_unit_module.implementation_part != null) - in_interface_part = true; - hard_node_test_and_visit(_unit_module.interface_part); - if (_unit_module.implementation_part != null) - in_interface_part = false; - if (_unit_module.attributes != null) - make_attributes_for_declaration(_unit_module, _compiled_unit); - context.leave_interface_part(); - _is_interface_part = false; - /*#if DEBUG - var fname = "C:\\st1.txt"; - if (System.IO.File.Exists(fname)) - System.IO.File.Delete(fname); - SymbolTable.ToString(); - System.IO.File.AppendAllText(fname, SymbolTable.Print()); - //var st = new SymbolTableVisitor("C:\\st1.txt", SymbolTable); - //st.PrintProgam(true); - #endif*/ - - } - - public void convert_pabc_namespaces(syntax_namespace_node[] namespaces) - { - context.namespace_converted = true; - Dictionary dict = new Dictionary(); - foreach (syntax_namespace_node _syntax_namespace_node in namespaces) - { - _syntax_namespace_node.referenced_units.AddRange(referenced_units); - var names = _syntax_namespace_node.name.Split('.'); - SymTable.Scope scope = null; - SymTable.Scope parent_scope = context.CurrentScope; - for (int i = 0; i < names.Length; i++) - { - var si_list = context.CurrentScope.Find(names[i]); - if (si_list == null) - { - List top_scopes = new List(); - top_scopes.AddRange(build_referenced_units(_syntax_namespace_node.referenced_units, false)); - if (parent_scope != context.CurrentScope) - top_scopes.Add(parent_scope); - scope = convertion_data_and_alghoritms.symbol_table.CreateNamespaceScope(top_scopes.ToArray(), parent_scope); - common_namespace_node cmn = new common_namespace_node(null, _compiled_unit, names[i], scope, null); - - parent_scope.AddSymbol(names[i], new SymbolInfo(cmn)); - scope.AddSymbol(names[i], new SymbolInfo(cmn)); - if (i == names.Length - 1) - { - dict.Add(_syntax_namespace_node, cmn); - var unit_scope = context.converted_namespace.scope as SymTable.UnitInterfaceScope; - if (unit_scope.TopScopeArray != null) - for (int j = 0; j < unit_scope.TopScopeArray.Length; j++) - { - if (unit_scope.TopScopeArray[j] is NetHelper.NetScope) - { - NetHelper.NetScope netScope = unit_scope.TopScopeArray[j] as NetHelper.NetScope; - if (netScope.used_namespaces.Count > 0 && string.Compare(netScope.used_namespaces[0].namespace_name, _syntax_namespace_node.name, true) == 0) - { - unit_scope.TopScopeArray[j] = scope; - } - } - } - } - - } - else - { - foreach (SymbolInfo si in si_list) - if (si.sym_info is common_namespace_node) - { - common_namespace_node cmn = si.sym_info as common_namespace_node; - scope = cmn.scope; - if (!(scope is SymTable.NamespaceScope)) - { - if (i == names.Length - 1) - dict.Add(_syntax_namespace_node, cmn); - } - break; - } - else if (si.sym_info is compiled_namespace_node) - { - List top_scopes = new List(); - top_scopes.AddRange(build_referenced_units(_syntax_namespace_node.referenced_units, false)); - if (parent_scope != context.CurrentScope) - top_scopes.Add(parent_scope); - compiled_namespace_node cnn = si.sym_info as compiled_namespace_node; - if (cnn.common_namespace == null) - { - scope = convertion_data_and_alghoritms.symbol_table.CreateNamespaceScope(top_scopes.ToArray(), parent_scope); - common_namespace_node cmn = new common_namespace_node(null, _compiled_unit, names[i], scope, null); - cnn.common_namespace = cmn; - } - else - scope = cnn.common_namespace.scope; - if (i == names.Length - 1 && !dict.ContainsKey(_syntax_namespace_node)) - dict.Add(_syntax_namespace_node, cnn.common_namespace); - } - - if (scope == null) - AddError(get_location(_syntax_namespace_node), "NAMESPACE_REDECLARATION"); - } - parent_scope = scope; - } - } - - foreach (syntax_namespace_node _syntax_namespace_node in namespaces) - { - var cmn = dict[_syntax_namespace_node]; - List scopes = new List(); - SymTable.UnitInterfaceScope ns_scope = cmn.scope as SymTable.UnitInterfaceScope; - if (ns_scope.TopScopeArray != null) - scopes.AddRange(ns_scope.TopScopeArray); - foreach (unit_node un in _syntax_namespace_node.referenced_units) - { - if (un is namespace_unit_node) - { - var nun = un as namespace_unit_node; - var names = nun.namespace_name.namespace_name.Split('.'); - var si_list = context.CurrentScope.Find(names[0]); - if (si_list != null && si_list.FirstOrDefault().sym_info is common_namespace_node) - { - SymTable.Scope ns_scope2 = (si_list.FirstOrDefault().sym_info as common_namespace_node).scope; - for (int i = 1; i < names.Length; i++) - { - si_list = ns_scope2.Find(names[i]); - if (si_list != null && si_list.FirstOrDefault().sym_info is common_namespace_node) - ns_scope2 = (si_list.FirstOrDefault().sym_info as common_namespace_node).scope; - else - AddError(new NamespaceNotFound(nun.namespace_name.namespace_name, un.location)); - } - scopes.Add(ns_scope2); - } - else if (si_list == null) - AddError(new NamespaceNotFound(nun.namespace_name.namespace_name, un.location)); - } - } - ns_scope.TopScopeArray = scopes.ToArray(); - } - - //convert type predefinitions - foreach (syntax_namespace_node _syntax_namespace_node in namespaces) - { - var cmn = dict[_syntax_namespace_node]; - var scope = cmn.scope; - context.enter_scope(scope); - foreach (declaration decl in _syntax_namespace_node.defs) - { - if (decl is type_declarations) - { - type_declarations type_decls = decl as type_declarations; - foreach (type_declaration td in type_decls.types_decl) - { - if (td.type_def is class_definition) - { - class_definition cl_def = td.type_def as class_definition; - if (cl_def.body == null) - AddError(get_location(cl_def), "TYPE_PREDEFINITION_NOT_ALLOWED"); - common_type_node ctn = null; - if (td.type_name is template_type_name) - ctn = context.advanced_create_type(td.type_name.name + "`" + (td.type_name as template_type_name).template_args.Count, get_location(td.type_name), (td.type_def as class_definition).keyword == class_keyword.Interface, (cl_def.attribute & SyntaxTree.class_attribute.Partial) == SyntaxTree.class_attribute.Partial, cl_def.attribute); - else - ctn = context.advanced_create_type(td.type_name.name, get_location(td.type_name), (td.type_def as class_definition).keyword == class_keyword.Interface, (cl_def.attribute & SyntaxTree.class_attribute.Partial) == SyntaxTree.class_attribute.Partial, cl_def.attribute); - ctn.ForwardDeclarationOnly = true; - if ((td.type_def as class_definition).keyword == class_keyword.Interface) - ctn.IsInterface = true; - context.converted_type = null; - context.add_type_header(td, ctn); - } - else if (td.type_def is procedure_header || td.type_def is function_header || td.type_def is named_type_reference) - { - - } - else if (td.type_def is enum_type_definition) - { - hard_node_test_and_visit(td); - } - else - AddError(get_location(decl), "NAMESPACE_SHOULD_CONTAINS_ONLY_TYPES"); - } - - } - else if (decl is procedure_definition && get_location(decl) == null) - { - //yield - } - else - AddError(get_location(decl), "NAMESPACE_SHOULD_CONTAINS_ONLY_TYPES"); - } - - context.leave_scope(); - } - - - foreach (syntax_namespace_node _syntax_namespace_node in namespaces) - { - common_namespace_node cmn = dict[_syntax_namespace_node]; - context.enter_scope(cmn.scope); - foreach (declaration decl in _syntax_namespace_node.defs) - { - if (decl is type_declarations) - { - type_declarations type_decls = decl as type_declarations; - foreach (type_declaration td in type_decls.types_decl) - { - if (td.type_def is procedure_header || td.type_def is function_header || td.type_def is named_type_reference) - { - hard_node_test_and_visit(td); - if (!(td.type_def is named_type_reference)) - { - common_type_node ctn = context.converted_namespace.types[context.converted_namespace.types.Count - 1]; - ctn.SetName(_syntax_namespace_node.name + "." + ctn.name); - } - } - } - } - } - context.leave_scope(); - } - foreach (syntax_namespace_node _syntax_namespace_node in namespaces) - { - common_namespace_node cmn = dict[_syntax_namespace_node]; - context.enter_scope(cmn.scope); - foreach (declaration decl in _syntax_namespace_node.defs) - { - if (decl is type_declarations) - { - type_declarations type_decls = decl as type_declarations; - foreach (type_declaration td in type_decls.types_decl) - { - if (td.type_def is class_definition) - { - hard_node_test_and_visit(td); - common_type_node ctn = context.converted_namespace.types[context.converted_namespace.types.Count - 1]; - ctn.SetName(_syntax_namespace_node.name + "." + ctn.name); - } - } - } - - } - context.leave_scope(); - } - foreach (syntax_namespace_node _syntax_namespace_node in namespaces) - { - common_namespace_node cmn = dict[_syntax_namespace_node]; - context.enter_scope(cmn.scope); - foreach (declaration decl in _syntax_namespace_node.defs) - { - if (decl is procedure_definition) - { - hard_node_test_and_visit(decl); - } - } - context.leave_scope(); - } - foreach (syntax_namespace_node _syntax_namespace_node in namespaces) - { - common_namespace_node cmn = dict[_syntax_namespace_node]; - context.enter_scope(cmn.scope); - foreach (declaration decl in _syntax_namespace_node.defs) - { - if (decl is type_declarations) - { - type_declarations type_decls = decl as type_declarations; - foreach (type_declaration td in type_decls.types_decl) - { - if (td.type_def is class_definition) - { - context.converted_type = context.get_type_to_realize(td); - class_definition cl_def = td.type_def as class_definition; - visit_class_member_realizations(cl_def.body); - context.converted_type = null; - } - } - } - } - context.leave_scope(); - } - context.namespace_converted = false; - context.clear_member_bindings(); - - } - - public override void visit(SyntaxTree.compilation_unit _compilation_unit) - { - if (_compilation_unit.source_context == null) - throw new NotSupportedError(); - throw new NotSupportedError(get_location(_compilation_unit)); - } - - public override void visit(SyntaxTree.program_body _program_body) - { - throw new NotSupportedError(get_location(_program_body)); - } - - public override void visit(SyntaxTree.uses_list _uses_list) - { - throw new NotSupportedError(get_location(_uses_list)); - } - - public override void visit(SyntaxTree.uses_unit_in _uses_unit_in) - { - throw new NotSupportedError(get_location(_uses_unit_in)); - } - - public override void visit(SyntaxTree.unit_name _unit_name) - { - throw new NotSupportedError(get_location(_unit_name)); - } - - public override void visit(SyntaxTree.consts_definitions_list _consts_definitions_list) - { - //ssyy - if (context.converting_block() == block_type.type_block && - context.converted_type.IsInterface) - { - AddError(get_location(_consts_definitions_list), "INVALID_INTERFACE_MEMBER"); - } - //\ssyy - foreach (SyntaxTree.const_definition cnst in _consts_definitions_list.const_defs) - cnst.visit(this); - } - - public override void visit(SyntaxTree.const_definition _const_definition) - { - throw new NotSupportedError(get_location(_const_definition)); - } - - private bool IsBoundedArray(type_node tn) - { - return tn.get_internal_interface(internal_interface_kind.bounded_array_interface) != null; - } - - private bool IsUnsizedArray(type_node tn) - { - return tn.get_internal_interface(internal_interface_kind.unsized_array_interface) != null; - } - - private type_node const_def_type=null; - private bool is_typed_const_def=false; - - public override void visit(SyntaxTree.typed_const_definition _typed_const_definition) - { - location cons_loc = get_location(_typed_const_definition.const_value); - constant_definition_node cdn = context.add_const_definition(_typed_const_definition.const_name.name, get_location(_typed_const_definition.const_name)); - type_node tn = convert_strong(_typed_const_definition.const_type); - assign_doc_info(cdn,_typed_const_definition); - check_for_type_allowed(tn,get_location(_typed_const_definition.const_type)); - check_using_static_class(tn, get_location(_typed_const_definition.const_type)); - if (context.converted_type != null && context.converted_func_stack.Empty) - if (!constant_in_class_valid(tn))//proverka na primitivnost konstanty v klasse - AddError(get_location(_typed_const_definition), "CLASS_CONSTANT_CAN_HAVE_ONLY_PRIMITIVE_VALUE"); - if (tn is common_type_node) - { - if (!SemanticRules.DefineMethodsInConstantRecord) - CheckConstantRecordNotBeContainsMethods(tn as common_type_node, get_location(_typed_const_definition.const_type)); - if (!SemanticRules.InheritanceConstantRecord) - //mnozhestvo zdes iskljuchenie - if (tn.base_type is common_type_node && tn.base_type.type_special_kind != SemanticTree.type_special_kind.base_set_type/*tn.base_type != SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node*/) - AddError(get_location(_typed_const_definition.const_type), "CONSTANT_RECORD_CAN_NOT_BE_INHERITANCE"); - } - const_def_type = tn.element_type; - is_typed_const_def = true; - _typed_const_definition.const_value = get_possible_array_const(_typed_const_definition.const_value,tn); - cdn.const_value = convert_strong_to_constant_node(_typed_const_definition.const_value, tn); - const_def_type = null; - is_typed_const_def = false; - if (cdn is class_constant_definition && cdn.constant_value.value == null) - AddError(new NotSupportedError(cons_loc)); - } - - private void CheckConstantRecordNotBeContainsMethods(common_type_node ctn, location loc) - { - if (ctn.is_value) - { - if (ctn.methods.Count > 0) - { - for (int i=0; i 1) - { - AddError(get_location(tpars.idents.idents[1]), "ONLY_ONE_PARAMS_PARAMETER_ALLOWED"); - } - } - - SyntaxTree.array_type arr = tpars.vars_type as SyntaxTree.array_type; - if (tpars.vars_type is SyntaxTree.class_definition || /*tpars.vars_type is SyntaxTree.enum_type_definition ||*/ - (arr != null && arr.indexers != null && arr.indexers.indexers.Count > 0 && arr.indexers.indexers[0] != null)) - { - AddError(get_location(tpars.vars_type), "STRUCT_TYPE_DEFINITION_IN_FORMAL_PARAM"); - } - - type_node tp = convert_strong(tpars.vars_type); - - if (tpars.param_kind == SyntaxTree.parametr_kind.params_parametr) - { - internal_interface ii = tp.get_internal_interface(internal_interface_kind.unsized_array_interface); - if (ii == null) - { - AddError(get_location(tpars.vars_type), "ONLY_UNSIZED_ARRAY_PARAMS_PARAMETER_ALLOWED"); - } - } - foreach (common_parameter ccp in temp_params) - { - ccp.type = tp; - } - - - if (params_met) - { - AddError(get_location(tpars), "ONLY_LAST_PARAMETER_CAN_BE_PARAMS"); - } - if (tpars.param_kind == PascalABCCompiler.SyntaxTree.parametr_kind.params_parametr) - { - params_met = true; - } - } - - } - type_node ret_val_type = null; - if (return_type != null) - { - ret_val_type = convert_strong(return_type); - } - common_type_node del; - if (del_type == null) - { - del = convertion_data_and_alghoritms.type_constructor.create_delegate(type_name, - ret_val_type, parameters, context.converted_namespace, loc); - } - else - { - del = del_type; - convertion_data_and_alghoritms.type_constructor.init_delegate(del, ret_val_type, parameters, loc); - } - context.converted_namespace.types.AddElement(del); - return del; - } - - private string get_template_instance_name(string template_name, System.Collections.Generic.List args) - { - System.Text.StringBuilder sb = new System.Text.StringBuilder(); - sb.Append("$"); - sb.Append("template_"); - sb.Append(template_name); - foreach (string s in args) - { - sb.Append("$"); - sb.Append(s); - } - return sb.ToString(); - } - - private string record_type_name = null; - private bool record_is_generic = false; - - private void check_where_section(SyntaxTree.class_definition cl_def) - { - if (cl_def.where_section != null && cl_def.where_section.defs != null) - { - AddError(get_location(cl_def.where_section), "WHERE_SECTION_ALLOWED_ONLY_IN_GENERICS"); - } - } - - //(ssyy) Проверяет параметры шаблона на совпадение друг с другом - private void check_param_redeclared(List idents) - { - for (int i = 0; i < idents.Count; i++) - for (int j = i + 1; j < idents.Count; j++) - { - if (string.Equals(idents[i].name, idents[j].name, StringComparison.InvariantCultureIgnoreCase)) - { - AddError(get_location(idents[j]), "TEMPLATE_PARAMETER_{0}_REDEFINITION", idents[j].name); - } - } - if (context.top_function != null && context.converted_type != null && context.converted_type.is_generic_type_definition) - { - //List gparams = context.converted_type.generic_params; - foreach (SyntaxTree.ident id in idents) - foreach(SemanticTree.ICommonTypeNode ictn in context.converted_type.generic_params) - if (string.Equals(id.name, ictn.name, StringComparison.InvariantCultureIgnoreCase)) - { - AddError(get_location(id), "TEMPLATE_PARAMETER_{0}_REDEFINITION", id.name); - } - } - } - - private void visit_generic_params(common_type_node ctn, List idents) - { - if (SemanticRules.RuntimeInitVariablesOfGenericParameters) - { - if (SystemLibrary.SystemLibInitializer.RuntimeInitializeFunction != null) // SSM 12/05/15 - из-за отсутствия этого падало при наличии обобщенных классов в системном модуле! Ужас! - SystemLibrary.SystemLibInitializer.RuntimeInitializeFunction.Restore(); - } - ctn.is_generic_type_definition = true; - check_param_redeclared(idents); - ctn.generic_params = new List(); - foreach (SyntaxTree.ident id in idents) - { - common_type_node par = new common_type_node( - id.name, SemanticTree.type_access_level.tal_public, context.converted_namespace, - convertion_data_and_alghoritms.symbol_table.CreateInterfaceScope(null, SystemLibrary.SystemLibrary.object_type.Scope, null), - get_location(id)); - SystemLibrary.SystemLibrary.init_reference_type(par); - par.SetBaseType(SystemLibrary.SystemLibrary.object_type); - par.generic_type_container = ctn; - ctn.generic_params.Add(par); - ctn.scope.AddSymbol(id.name, new SymbolInfo(par)); - if (SemanticRules.RuntimeInitVariablesOfGenericParameters && !ctn.IsInterface && !ctn.IsDelegate) - { - class_field cf = new class_field( - compiler_string_consts.generic_param_kind_prefix + id.name, - SystemLibrary.SystemLibrary.byte_type, - ctn, PascalABCCompiler.SemanticTree.polymorphic_state.ps_static, - SemanticTree.field_access_level.fal_public, null); - ctn.fields.AddElement(cf); - par.runtime_initialization_marker = cf; - } - } - } - - private void visit_generic_params(common_function_node cfn, List idents) - { - check_param_redeclared(idents); - cfn.generic_params = new List(); - foreach (SyntaxTree.ident id in idents) - { - common_type_node par = new common_type_node( - id.name, SemanticTree.type_access_level.tal_public, context.converted_namespace, - convertion_data_and_alghoritms.symbol_table.CreateInterfaceScope(null, SystemLibrary.SystemLibrary.object_type.Scope, null), - get_location(id)); - // voloshinbogdan 2018.05.21 Fix missing attributes translation for generic parameters - make_attributes_for_declaration(id, par); - SystemLibrary.SystemLibrary.init_reference_type(par); - par.SetBaseType(SystemLibrary.SystemLibrary.object_type); - par.generic_function_container = cfn; - cfn.generic_params.Add(par); - cfn.scope.AddSymbol(id.name, new SymbolInfo(par)); - } - } - - - public override void visit(SyntaxTree.type_declaration _type_declaration) - { - if (_type_declaration.type_name.name.ToLower() == "program") - { - AddError(get_location(_type_declaration), "PROGRAM_NAME_FOR_TYPE_NAME_IS_PROHIBITED"); - } - //bool is_template_synonym = false; - //SyntaxTree.array_type at=_type_declaration.type_def as SyntaxTree.array_type; - - if (_type_declaration.type_def is class_definition cd && cd.keyword == class_keyword.Class && - (cd.attribute & SyntaxTree.class_attribute.Static) == SyntaxTree.class_attribute.Static) - { - var name = _type_declaration.type_name.name.ToLower(); - if(context.types_predefined.Select(tn => tn.name.ToLower()).Contains(name)) - AddError(get_location(_type_declaration), "STATIC_CLASS_CANNOT_HAVE_PREDEFINITION"); // #2266 - } - - - template_class tc = null; - SyntaxTree.template_type_name ttn = _type_declaration.type_name as SyntaxTree.template_type_name; - SyntaxTree.class_definition cl_def = _type_declaration.type_def as SyntaxTree.class_definition; - SyntaxTree.function_header function_header = _type_declaration.type_def as SyntaxTree.function_header; - SyntaxTree.procedure_header procedure_header = _type_declaration.type_def as SyntaxTree.procedure_header; - if (cl_def != null && (cl_def.attribute & SyntaxTree.class_attribute.Partial) == SyntaxTree.class_attribute.Partial && cl_def.keyword != SyntaxTree.class_keyword.Class) - { - AddError(get_location(_type_declaration), "ONLY_CLASS_CAN_BE_PARTIAL"); - } - if (ttn != null && cl_def == null && function_header == null && procedure_header == null) - { - location t_loc = get_location(ttn); - context.check_name_free(ttn.name, t_loc); - tc = new template_class(_type_declaration, ttn.name, - context.converted_namespace, - current_document, using_list); - tc.is_synonym = true; - //Проверяем параметры шаблона на совпадение друг с другом - check_param_redeclared(ttn.template_args.idents); - context.AddTemplate(ttn.name, tc, t_loc); - - // SSM 23.10.18. Bug fix #1395. Пытаемся проверить, что это - enum. Повторяем с изменениями код в enum_type_node - if (_type_declaration.type_def is enum_type_definition etd) - { - // значит это возможно enum - //var etd = - foreach (SyntaxTree.enumerator en in etd.enumerators.enumerators) - { - if (!((en.name is named_type_reference) && (en.name as named_type_reference).names.Count() == 1)) - { - // Это tupletype - return; - } - // Все - идентификаторы. Проверяем дальше - SyntaxTree.ident id = (en.name as named_type_reference).FirstIdent; - - // Если равен какому-то имени в параметрах обобщения, то это тип - пропускаем. Ищем не тип или неизвестное имя - if (ttn.template_args.idents.Select(ide => ide.name.ToLower()).Any(s => s.Equals(id.name.ToLower()))) - continue; - var si = context.CurrentScope.Find(id.name); - if ((si == null) || !(si.FirstOrDefault().sym_info is type_node)) - { - // Это точно enum. Выдавать ошибку - enumы не могут быть обобщёнными - AddError(get_location(ttn), "ENUMS_CANNOT_BE_GENERIC"); - } - } - } - // Это не enum. Значит, просто выйти. Так было в коде до SSM 23.10.18 - - return; - - //is_template_synonym = true; - //AddError(new TemplateCanBeClassOnly(get_location(ttn))); - } - if ((function_header != null) || (procedure_header != null)) - { - location loc; - if (function_header != null) - loc = get_location(function_header); - else - loc = get_location(procedure_header); - string del_name = _type_declaration.type_name.name; - if (ttn != null) - { - if (context.top_function != null) - { - AddError(loc, "GENERIC_DELEGATE_INNER_FUNCTION"); - } - del_name += compiler_string_consts.generic_params_infix + ttn.template_args.idents.Count; - } - context.check_name_free(del_name, loc); - common_type_node del_type = convertion_data_and_alghoritms.type_constructor.create_delegate_without_init( - del_name, context.converted_namespace, loc); - //(ssyy) Обработка дженериков - common_type_node tmp_converted_type = null; - if (ttn != null) - { - tmp_converted_type = context.converted_type; - context.converted_type = del_type; - visit_generic_params(del_type, ttn.template_args.idents); - } - if (function_header != null) - { - del_type = convert_function_type(function_header, loc, del_name, del_type); - } - else - { - del_type = convert_function_type(procedure_header, loc, del_name, del_type); - } - if (ttn != null) - { - context.converted_type = tmp_converted_type; - } - //blocks.converted_namespace.types.AddElement(del_type); - CheckWaitedRefTypes(del_type); - if (_type_declaration.attributes != null) - { - make_attributes_for_declaration(_type_declaration,del_type); - } - context.converted_namespace.scope.AddSymbol(del_name, new SymbolInfo(del_type)); - return; - } - if (cl_def == null && ttn == null) - { - string name = _type_declaration.type_name.name; - location loc = get_location(_type_declaration.type_name); - context.check_name_free(name, loc); - is_direct_type_decl = true; - type_node tn = convert_strong(_type_declaration.type_def); - assign_doc_info(tn,_type_declaration); - is_direct_type_decl = false; - if (_type_declaration.type_def is SyntaxTree.named_type_reference|| - _type_declaration.type_def is SyntaxTree.ref_type || _type_declaration.type_def is SyntaxTree.string_num_definition || - _type_declaration.type_def is SyntaxTree.sequence_type || //SSM 01.11.2018 - tn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.array_kind)// || - /*tn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.set_type*/ - { - if (context.converted_func_stack.Empty) - { - type_synonym ts = new type_synonym(name, tn, loc); - assign_doc_info(ts,_type_declaration); - context.converted_namespace.type_synonyms.Add(ts); - } - } - else - { - tn.SetName(context.BuildName(name)); - } - if (_type_declaration.attributes != null) - if (_type_declaration.type_def is SyntaxTree.enum_type_definition) - { - make_attributes_for_declaration(_type_declaration,tn); - (tn as common_type_node).add_additional_enum_operations(); - } - else - AddError(get_location(_type_declaration.attributes), "ATTRIBUTES_APPLICABLE_ONLY_TO_THESE_TYPES"); - context.add_type(name, tn, loc); - return; - } - //Проверим, что список template-ов не пуст - bool is_generic = false; - if (ttn != null && cl_def != null && cl_def.template_args == null) - { - cl_def.template_args = ttn.template_args; - } - if (cl_def != null && cl_def.template_args != null && cl_def.template_args.idents != null && - cl_def.template_args.idents.Count > 0) - { - switch (cl_def.keyword) - { - case PascalABCCompiler.SyntaxTree.class_keyword.TemplateClass: - cl_def.keyword = PascalABCCompiler.SyntaxTree.class_keyword.Class; - is_generic = false; - check_where_section(cl_def); - break; - case PascalABCCompiler.SyntaxTree.class_keyword.TemplateRecord: - cl_def.keyword = PascalABCCompiler.SyntaxTree.class_keyword.Record; - is_generic = false; - check_where_section(cl_def); - break; - case PascalABCCompiler.SyntaxTree.class_keyword.TemplateInterface: - cl_def.keyword = PascalABCCompiler.SyntaxTree.class_keyword.Interface; - is_generic = false; - check_where_section(cl_def); - break; - default: - is_generic = true; - break; - } - - if (!is_generic) - { - string t_name = _type_declaration.type_name.name; - location t_loc = get_location(_type_declaration.type_name); - List sil = context.find_only_in_namespace(t_name); - - tc = null; - //Ищем предописание - if (sil != null) - { - tc = sil.FirstOrDefault().sym_info as template_class; - if (tc == null || !tc.ForwardDeclarationOnly) - { - AddError(new NameRedefinition(t_name, convertion_data_and_alghoritms.get_location(sil.FirstOrDefault().sym_info), t_loc)); - } - SyntaxTree.class_definition prev_cl_def = tc.type_dec.type_def as SyntaxTree.class_definition; - if (prev_cl_def.keyword != cl_def.keyword || prev_cl_def.template_args.idents.Count != cl_def.template_args.idents.Count) - { - AddError(t_loc, "FORWARD_TEMPLATE_{0}_DECLARATION_MISMATCH_DECLARATION", t_name); - } - for (int k = 0; k < cl_def.template_args.idents.Count; k++) - { - if (string.Compare(cl_def.template_args.idents[k].name, prev_cl_def.template_args.idents[k].name, true) != 0) - { - AddError(t_loc, "FORWARD_TEMPLATE_{0}_DECLARATION_MISMATCH_DECLARATION", t_name); - } - } - if (cl_def.body == null) - { - AddError(new NameRedefinition(t_name, convertion_data_and_alghoritms.get_location(sil.FirstOrDefault().sym_info), t_loc)); - } - tc.type_dec = _type_declaration; - tc.ForwardDeclarationOnly = false; - return; - } - - tc = new template_class(_type_declaration, t_name, - context.converted_namespace, - current_document, using_list); - - //Проверяем параметры шаблона на совпадение друг с другом - check_param_redeclared(cl_def.template_args.idents); - - tc.ForwardDeclarationOnly = cl_def.body == null; - context.AddTemplate(t_name, tc, t_loc); - if (!tc.ForwardDeclarationOnly && template_class.check_template_definitions) - { - int count = cl_def.template_args.idents.Count; - List test_types = new List(count); - for (int i = 0; i < count; i++) - { - test_types.Add(new indefinite_type_node(cl_def.template_args.idents[i].name)); - } - instance(tc, test_types, t_loc); - } - return; - } - } - //(ssyy) Теперь проверим на модификатор template - if (cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.TemplateClass || - cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.TemplateRecord || - cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.TemplateInterface) - { - //Ошибка, т.к. нет списка шаблонных параметров. - AddError(get_location(_type_declaration.type_name), "TEMPLATE_PARAMS_EXPECTED"); - } - bool predefined_generic = false; - if (is_generic) - { - List sil = context.find_only_in_namespace(_type_declaration.type_name.name + compiler_string_consts.generic_params_infix + - cl_def.template_args.idents.Count.ToString()); - if (!(sil != null && sil.FirstOrDefault().sym_info is common_type_node && ((sil.FirstOrDefault().sym_info as common_type_node).IsPartial || context.types_predefined.IndexOf(sil.FirstOrDefault().sym_info as common_type_node) != -1))) - { - context.check_name_free(_type_declaration.type_name.name, get_location(_type_declaration.type_name)); - } - else - predefined_generic = true; - _type_declaration.type_name.name += compiler_string_consts.generic_params_infix + - cl_def.template_args.idents.Count.ToString(); - } - if (cl_def.keyword == SyntaxTree.class_keyword.Record) - { - string name = record_type_name = _type_declaration.type_name.name; - if (context.top_function != null && context.top_function.generic_params != null) - { - AddError(get_location(_type_declaration.type_name), "NESTED_RECORDS_IN_GENERIC_FUNCTIONS_NOT_ALLOWED"); - } - record_is_generic = is_generic; - location loc = get_location(_type_declaration.type_name); - context.check_name_free(name, loc); - //context.create_record_type(loc, record_type_name); - is_direct_type_decl = true; - type_node tn = convert_strong(_type_declaration.type_def); - assign_doc_info(tn,_type_declaration); - if (_type_declaration.attributes != null) - { - make_attributes_for_declaration(_type_declaration, tn); - } - is_direct_type_decl = false; - record_type_name = null; - record_is_generic = false; - tn.SetName(context.BuildName(name)); - return; - } - - //(ssyy) Флаг показывает, создаём ли мы интерфейс - bool interface_creating = (cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.Interface); - - common_type_node ctn = context.advanced_create_type(_type_declaration.type_name.name, get_location(_type_declaration.type_name), interface_creating, (cl_def.attribute & SyntaxTree.class_attribute.Partial) == SyntaxTree.class_attribute.Partial, cl_def.attribute); - assign_doc_info(ctn,_type_declaration); - if (_type_declaration.attributes != null) - { - make_attributes_for_declaration(_type_declaration, ctn); - } - if (cl_def.keyword == class_keyword.Class || cl_def.keyword == class_keyword.Interface) - ctn.is_class = true;//nado ranshe pomechat kak is_class - if (is_generic) - { - if (predefined_generic) - { - if (ctn.generic_params.Count != cl_def.template_args.idents.Count) - AddError(get_location(cl_def.template_args), "GENERIC_PARAMETERS_MISMATCH"); - foreach (ident id in cl_def.template_args.idents) - { - SymbolInfo si = ctn.find_first_in_type(id.name); - if (si == null) - AddError(get_location(cl_def.template_args), "GENERIC_PARAMETERS_MISMATCH"); - if (!(si.sym_info is common_type_node && (si.sym_info as common_type_node).is_generic_parameter)) - AddError(get_location(cl_def.template_args), "GENERIC_PARAMETERS_MISMATCH"); - } - } - else - { - context.create_generic_indicator(ctn); - visit_generic_params(ctn, cl_def.template_args.idents); - } - } - if (predefined_generic && cl_def.where_section != null && cl_def.where_section.defs.Count > 0) - AddError(get_location(cl_def.where_section), "WHERE_SECTION_NOT_ALLOWED"); - if ((cl_def.attribute & SyntaxTree.class_attribute.Partial) == SyntaxTree.class_attribute.Partial && cl_def.class_parents != null) - { - type_node tn = ret.visit(cl_def.class_parents.types[0]); - if (!tn.IsInterface && ctn.base_type != SemanticRules.ClassBaseType && ctn.base_type != null && !ctn.base_type.IsInterface && tn != ctn.base_type) - AddError(get_location(cl_def.class_parents), "PARTIAL_CLASS_PARENTS_MISMATCH"); - /*if (ctn.ImplementingInterfaces.Count != cl_def.class_parents.types.Count - 1) - AddError(get_location(cl_def.class_parents), "PARTIAL_CLASS_PARENTS_MISMATCH"); - for (int i=1; i < cl_def.class_parents.types.Count; i++) - { - tn = ret.visit(cl_def.class_parents.types[i]); - if (ctn.ImplementingInterfaces[i-1] != tn) - AddError(get_location(cl_def.class_parents.types[i]), "PARTIAL_CLASS_PARENTS_MISMATCH"); - }*/ - } - - visit_where_list(cl_def.where_section); - - CheckWaitedRefTypes(ctn); - is_direct_type_decl = true; - hard_node_test_and_visit(_type_declaration.type_def); - check_where_from_base_class(ctn); - // frninja 28/04/16 - режем мусорные методы хелперы yield - { - var toRemove = ctn.methods.Where(m => m.is_yield_helper).ToArray(); - foreach (var m in toRemove) - { - ctn.methods.remove(m); - } - } - // end frninja - - is_direct_type_decl = false; - } - - private bool attribute_converted = false; - private AttributeTargets get_usage_attrs(type_node tn, out bool allowMultiple) - { - allowMultiple = false; - if (tn is common_type_node) - { - common_type_node ctn = tn as common_type_node; - for (int i=0; i cnst_list = new List(); - foreach (expression_node ex in (en as array_initializer).element_values) - { - constant_node elem_cn = convert_strong_to_constant_node(ex, ex.type); - check_for_strong_constant(elem_cn, ex.location); - cnst_list.Add(elem_cn); - } - - cn = convert_strong_to_constant_node(new array_const(cnst_list, en.location), en.type); - } - else - { - cn = convert_strong_to_constant_node(en, en.type); - check_for_strong_constant(cn, en.location); - } - - attr_node.args.Add(cn); - } - if (attr.arguments != null) - { - for (int i = cnstr_args.expressions.Count; i < attr.arguments.expressions.Count; i++) - { - SyntaxTree.expression e = attr.arguments.expressions[i]; - if (!(e is SyntaxTree.bin_expr && (e as SyntaxTree.bin_expr).operation_type == SyntaxTree.Operators.Equal - && (e as SyntaxTree.bin_expr).left is SyntaxTree.ident)) - { - AddError(get_location(e), "EXPECTED_ATTRIBUTE_INITIALIZER"); - } - else - { - SyntaxTree.ident id = (e as SyntaxTree.bin_expr).left as SyntaxTree.ident; - SymbolInfo si = tn.find_first_in_type(id.name); - definition_node dn; - if (si != null) - dn = context.check_name_node_type(id.name, si, get_location(id), general_node_type.property_node, general_node_type.variable_node); - else - dn = context.check_name_node_type(id.name, null, get_location(id), general_node_type.property_node, general_node_type.variable_node); - type_node mem_tn = null; - if (dn is property_node) - { - property_node pn = dn as property_node; - attr_node.prop_names.Add(pn); - if (pn.set_function == null) - AddError(new ThisPropertyCanNotBeWrited(pn, get_location(id))); - if (pn.set_function.parameters.Count != 1) - AddError(get_location(id), "INDEX_PROPERTY_INITIALIZING_NOT_VALID"); - mem_tn = pn.set_function.parameters[0].type; - } - else if (dn is var_definition_node) - { - attr_node.field_names.Add(dn as var_definition_node); - mem_tn = (dn as var_definition_node).type; - } - else - { - throw new CompilerInternalError("Bad general node type for attribute initializer"); - } - //SyntaxTree.assign tmp_ass = new SyntaxTree.assign(id,(e as SyntaxTree.bin_expr).right,SyntaxTree.Operators.Assignment); - //tmp_ass.source_context = e.source_context; - //basic_function_call tmp_bfc = convert_strong(tmp_ass) as basic_function_call; - constant_node cn = convert_strong_to_constant_node((e as SyntaxTree.bin_expr).right, mem_tn); - check_for_strong_constant(cn, get_location((e as SyntaxTree.bin_expr).right)); - if (dn is property_node) - attr_node.prop_initializers.Add(cn); - else - attr_node.field_initializers.Add(cn); - } - } - } - attr_node.qualifier = qualifier; - ctn.attributes.AddElement(attr_node); - } - } - } - - private void make_attributes_for_declaration(SyntaxTree.unit_module un, common_unit_node cun) - { - if (cun.attributes != null) - { - Hashtable ht = new Hashtable(); - foreach (SyntaxTree.simple_attribute_list sal in un.attributes.attributes) - for (int j = 0; j < sal.attributes.Count; j++) - { - SyntaxTree.attribute attr = sal.attributes[j]; - attribute_converted = true; - type_node tn = convert_strong(attr.type); - bool is_attr = false; - type_node tmp = tn; - while (tmp.base_type != null && !is_attr) - { - is_attr = tmp.base_type == SystemLibrary.SystemLibrary.attribute_type; - tmp = tmp.base_type; - } - if (!is_attr) - AddError(get_location(attr), "CLASS_{0}_NOT_ATTRIBUTE", tn.name); - bool allowMultiple = false; - AttributeTargets targets = get_usage_attrs(tn, out allowMultiple); - if (ht.Contains(tn) && !allowMultiple) - { - AddError(get_location(attr), "DUPLICATE_ATTRIBUTE_{0}_APPLICATION", tn.name); - } - else - ht[tn] = tn; - SemanticTree.attribute_qualifier_kind qualifier = SemanticTree.attribute_qualifier_kind.none_kind; - if (attr.qualifier != null) - if (j == 0) - { - if (string.Compare(attr.qualifier.name, "return", true) == 0) - { - if (context.top_function == null) - AddError(get_location(attr), "ATTRIBUTE_APPLICABLE_ONLY_TO_METHOD"); - if (context.top_function.return_value_type == null || context.top_function.return_value_type == SystemLibrary.SystemLibrary.void_type) - AddError(get_location(attr), "EXPECTED_RETURN_VALUE_FOR_ATTRIBUTE"); - throw new NotSupportedError(get_location(attr.qualifier)); - qualifier = SemanticTree.attribute_qualifier_kind.return_kind; - } - else - throw new NotSupportedError(get_location(attr.qualifier)); - } - else - AddError(get_location(attr.qualifier), "ATTRIBUTE_QUALIFIER_MUST_BE_FIRST"); - check_for_usage_attribute(cun, targets, tn.name, get_location(attr), qualifier); - - attribute_converted = false; - SyntaxTree.expression_list cnstr_args = new SyntaxTree.expression_list(); - if (attr.arguments != null) - { - foreach (SyntaxTree.expression e in attr.arguments.expressions) - { - if (e is SyntaxTree.bin_expr && (e as SyntaxTree.bin_expr).operation_type == SyntaxTree.Operators.Equal - && (e as SyntaxTree.bin_expr).left is SyntaxTree.ident) - { - break; - } - else - { - cnstr_args.expressions.Add(e); - } - } - } - expressions_list args = new expressions_list(); - for (int i = 0; i < cnstr_args.expressions.Count; i++) - { - constant_node cn = convert_strong_to_constant_node(cnstr_args.expressions[i]); - check_for_strong_constant(cn, get_location(cnstr_args.expressions[i])); - args.AddElement(cn); - } - - base_function_call bfc = create_constructor_call(tn, args, get_location(attr)); - attribute_node attr_node = new attribute_node(bfc.simple_function_node, tn, get_location(un)); - foreach (expression_node en in bfc.parameters) - { - constant_node cn = convert_strong_to_constant_node(en, en.type); - check_for_strong_constant(cn, en.location); - attr_node.args.Add(cn); - } - if (attr.arguments != null) - { - for (int i = cnstr_args.expressions.Count; i < attr.arguments.expressions.Count; i++) - { - SyntaxTree.expression e = attr.arguments.expressions[i]; - if (!(e is SyntaxTree.bin_expr && (e as SyntaxTree.bin_expr).operation_type == SyntaxTree.Operators.Equal - && (e as SyntaxTree.bin_expr).left is SyntaxTree.ident)) - { - AddError(get_location(e), "EXPECTED_ATTRIBUTE_INITIALIZER"); - } - else - { - SyntaxTree.ident id = (e as SyntaxTree.bin_expr).left as SyntaxTree.ident; - List sil = tn.find(id.name); - definition_node dn; - if(sil != null) - dn = context.check_name_node_type(id.name, sil?.FirstOrDefault(), get_location(id), general_node_type.property_node, general_node_type.variable_node); - else - dn = context.check_name_node_type(id.name, null, get_location(id), general_node_type.property_node, general_node_type.variable_node); - type_node mem_tn = null; - if (dn is property_node) - { - property_node pn = dn as property_node; - attr_node.prop_names.Add(pn); - if (pn.set_function == null) - AddError(new ThisPropertyCanNotBeWrited(pn, get_location(id))); - if (pn.set_function.parameters.Count != 1) - AddError(get_location(id), "INDEX_PROPERTY_INITIALIZING_NOT_VALID"); - mem_tn = pn.set_function.parameters[0].type; - } - else if (dn is var_definition_node) - { - attr_node.field_names.Add(dn as var_definition_node); - mem_tn = (dn as var_definition_node).type; - } - else - { - throw new CompilerInternalError("Bad general node type for attribute initializer"); - } - constant_node cn = convert_strong_to_constant_node((e as SyntaxTree.bin_expr).right, mem_tn); - check_for_strong_constant(cn, get_location((e as SyntaxTree.bin_expr).right)); - if (dn is property_node) - attr_node.prop_initializers.Add(cn); - else - attr_node.field_initializers.Add(cn); - } - } - } - attr_node.qualifier = qualifier; - cun.attributes.AddElement(attr_node); - if (cun.namespaces.Count > 0) - cun.namespaces[0].attributes.AddElement(attr_node); - } - } - } - - private void check_for_strong_constant(constant_node cn, location loc) - { - switch (cn.semantic_node_type) - { - case semantic_node_type.bool_const_node : - case semantic_node_type.byte_const_node : - case semantic_node_type.char_const_node : - case semantic_node_type.sbyte_const_node : - case semantic_node_type.short_const_node : - case semantic_node_type.ushort_const_node : - case semantic_node_type.int_const_node : - case semantic_node_type.uint_const_node : - case semantic_node_type.long_const_node : - case semantic_node_type.ulong_const_node : - case semantic_node_type.float_const_node : - case semantic_node_type.double_const_node : - case semantic_node_type.string_const_node : - case semantic_node_type.enum_const : - case semantic_node_type.null_const_node : - return; - default: - AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); - break; - } - } - - internal void check_using_static_class(type_node tn, location loc) - { - if (tn.IsStatic) - AddError(loc, "USING_STATIC_CLASS_NOT_VALID"); - } - - internal void check_for_type_allowed(type_node tn, location loc) - { - if (tn == SystemLibrary.SystemLibrary.void_type) - AddError(loc, "TYPE_{0}_NOT_VALID", tn.name); - } - - private void check_cycle_inheritance(common_type_node cnode, type_node base_of_cnode) - { - List base_params = new List(); - base_params.Add(cnode); - common_type_node bt = base_of_cnode as common_type_node; - while (bt != null && bt.is_generic_parameter) - { - if (base_params.Contains(bt)) - { - AddError(bt.loc, "TYPE_{0}_DERIVED_FROM_ITSELF", bt.name); - } - base_params.Add(bt); - bt = bt.base_type as common_type_node; - } - } - - private void check_cycle_interface_inheritance(common_type_node cnode, type_node base_of_cnode, List interfaces) - { - // Для интерфейсов всё это излишне. Поскольку нельзя использовать предописанные интерфейсы в списке наследования, то - // циклически интерфейс может наследовать только от себя. Поэтому достаточно проверять нерекурсивно свой список ImplementingInterfaces и если там есть этот интерфейс, то ошибка - if (!cnode.IsInterface) - return; - interfaces.Add(cnode); - common_type_node bt = base_of_cnode as common_type_node; - if (bt != null && bt.original_generic != null) - bt = bt.original_generic as common_type_node; - if (bt != null) - { - if (interfaces.Contains(bt)) - { - AddError(bt.loc, "TYPE_{0}_DERIVED_FROM_ITSELF", bt.PrintableName); - } - interfaces.Add(bt); - foreach (var tn in bt.ImplementingInterfaces) - { - check_cycle_interface_inheritance(bt, tn as type_node, interfaces); - } - } - } - - private void check_where_from_base_class(common_type_node ctn) - { - if (ctn.base_type != null && ctn.base_type.is_generic_type_instance && ctn.is_generic_type_definition) - { - common_type_node bctn = ctn.base_type.original_generic as common_type_node; - compiled_type_node bctn2 = ctn.base_type.original_generic as compiled_type_node; - Dictionary where_cache = new Dictionary(); - foreach (SemanticTree.ICommonTypeNode t in ctn.generic_params) - { - int ind = ctn.base_type.instance_params.IndexOf(t as type_node); - if (ind != -1) - { - if (bctn != null) - where_cache.Add(bctn.generic_params[ind].name, t); - else - where_cache.Add(bctn2.generic_params[ind].name, t); - } - - } - if (bctn != null && bctn.generic_params != null) - { - foreach (SemanticTree.ICommonTypeNode t in bctn.generic_params) - { - SemanticTree.ICommonTypeNode thist = null; - where_cache.TryGetValue(t.name, out thist); - if (thist == null) - continue; - if (t.is_class || t.is_value_type || t.methods.Length > 0 || t.base_type != SystemLibrary.SystemLibrary.object_type) - { - - //if (thist.is_class != t.is_class || thist.is_value_type != t.is_value_type /*&& !(t.is_value_type && thist.base_type.is_value_type)*/ // последнее непонятно - // || thist.methods.Length != t.methods.Length || // это наличие конструктора - // t.base_type != thist.base_type && !type_table.is_derived(t.base_type as type_node, thist.base_type as type_node)) - if (t.is_class && !thist.is_class) - AddError(ctn.loc, "WHERE_SPECIFIER_MISMATCH"); - if (t.is_value_type && !thist.is_value_type) - AddError(ctn.loc, "WHERE_SPECIFIER_MISMATCH"); - if (t.methods.Length > thist.methods.Length) - AddError(ctn.loc, "WHERE_SPECIFIER_MISMATCH"); - if (t.base_type != SystemLibrary.SystemLibrary.object_type && !type_table.is_type_or_original_generics_equal(t.base_type as type_node, thist.base_type as type_node)) - AddError(ctn.loc, "WHERE_SPECIFIER_MISMATCH"); - - } - } - } - else if (bctn2 != null && bctn2.generic_params != null) - { - foreach (compiled_type_node t in bctn2.generic_params) - { - SemanticTree.ICommonTypeNode thist = null; - where_cache.TryGetValue(t.name, out thist); - if (thist == null) - continue; - if (t.is_value_type || t.base_type != SystemLibrary.SystemLibrary.object_type) - { - if (thist.is_value_type != t.is_value_type && !(t.is_value_type && thist.base_type.is_value_type) || thist.base_type != t.base_type) - AddError(ctn.loc, "WHERE_SPECIFIER_MISMATCH"); - } - } - } - } - } - - private void visit_where_list(SyntaxTree.where_definition_list where_list) - { - if (where_list == null) - { - return; - } - context.BeginSkipGenericInstanceChecking(); - List gparams = null; - common_function_node cfn = context.top_function; - if (cfn != null) - { - if (!cfn.is_generic_function) - { - AddError(get_location(where_list), "WHERE_SECTION_ALLOWED_ONLY_IN_GENERICS"); - return; - } - gparams = cfn.generic_params; - } - else - { - if (!context.converted_type.is_generic_type_definition) - { - AddError(get_location(where_list), "WHERE_SECTION_ALLOWED_ONLY_IN_GENERICS"); - return; - } - gparams = context.converted_type.generic_params; - } - List used_types = new List(where_list.defs.Count); - foreach (SyntaxTree.where_definition wd in where_list.defs) - { - foreach (SyntaxTree.ident wd_id in wd.names.idents) - { - bool param_not_found = true; - foreach (common_type_node param in gparams) - { - if (String.Equals(param.name, wd_id.name, StringComparison.InvariantCultureIgnoreCase)) - { - //Нашли нужный шаблонный параметр - if (used_types.Contains(param)) - { - AddError(get_location(wd.names), "SPECIFICATORS_FOR_{0}_ALREADY_EXIST", wd_id.name); - } - add_generic_eliminations(param, wd.types.defs); - used_types.Add(param); - param_not_found = false; - break; - } - } - if (param_not_found) - { - AddError(new UndefinedNameReference(wd.names.idents[0].name, get_location(wd.names))); - } - } - } - context.EndSkipGenericInstanceChecking(); - } - - //Добавляет ограничители для параметра шаблона - private void add_generic_eliminations(common_type_node param, List specificators) - { - Hashtable used_interfs = new Hashtable(); - for (int i = 0; i < specificators.Count; ++i) - { - SyntaxTree.declaration_specificator ds = specificators[i] as SyntaxTree.declaration_specificator; - if (ds != null) - { - switch (ds.specificator) - { - case SyntaxTree.DeclarationSpecificator.WhereDefClass: - if (i == 0) - { - param.is_class = true; - } - else - { - AddError(get_location(specificators[i]), "CLASS_OR_RECORD_SPECIFICATOR_MUST_BE_FIRST"); - } - break; - case SyntaxTree.DeclarationSpecificator.WhereDefValueType: - if (i == 0) - { - param.internal_is_value = true; - } - else - { - AddError(get_location(specificators[i]), "CLASS_OR_RECORD_SPECIFICATOR_MUST_BE_FIRST"); - } - break; - case SyntaxTree.DeclarationSpecificator.WhereDefConstructor: - if (i == specificators.Count - 1) - { - generic_parameter_eliminations.add_default_ctor(param); - } - else - { - AddError(get_location(specificators[i]), "CONSTRUCTOR_SPECIFICATOR_MUST_BE_LAST"); - } - break; - } - } - else - { - SyntaxTree.named_type_reference ntr = specificators[i] as SyntaxTree.named_type_reference; - if (ntr == null) - { - AddError(get_location(specificators[i]), "SPECIFICATOR_MUST_BE_TYPE_REFERENCE"); - } - else - { - type_node spec_type = ret.visit(ntr); - if (spec_type is ref_type_node || spec_type == SystemLibrary.SystemLibrary.void_type || spec_type == SystemLibrary.SystemLibrary.pointer_type) - AddError(new SimpleSemanticError(get_location(specificators[i]), "INAVLID_TYPE")); - //if (spec_type.is_class) - // param.is_class = true; - if (spec_type.IsInterface) - { - if (used_interfs[spec_type] != null) - { - AddError(get_location(specificators[i]), "INTERFACE_{0}_ALREADY_ADDED_TO_IMPLEMENTING_LIST", spec_type.PrintableName); - } - else - { - used_interfs.Add(spec_type, spec_type); - } - //Добавляем интерфейс - type_table.AddInterface(param, spec_type, get_location(specificators[i])); - } - else - { - if (i != 0) - { - AddError(get_location(specificators[i]), "PARENT_SPECIFICATOR_MUST_BE_FIRST"); - } - else - { - if (spec_type.is_value) - AddError(get_location(specificators[i]), "RECORD_CAN_NOT_BE_USED_AS_PARENT_SPECIFICATOR"); - //Тип-предок - if (spec_type == SystemLibrary.SystemLibrary.object_type) - { - AddError(get_location(specificators[i]), "OBJECT_CAN_NOT_BE_USED_AS_PARENT_SPECIFICATOR"); - } - /*if (spec_type == SystemLibrary.SystemLibrary.enum_base_type) - { - AddError(get_location(specificators[i]), "ENUM_CAN_NOT_BE_USED_AS_PARENT_SPECIFICATOR"); - }*/ - if (spec_type.IsStatic) - AddError(get_location(specificators[i]), "STATIC_CLASS_CAN_NOT_BE_USED_AS_PARENT_SPECIFICATOR"); - check_cycle_inheritance(param, spec_type); - param.SetBaseType(spec_type); - } - } - } - } - } - InitInterfaceScope(param); - } - - private bool is_direct_type_decl = false; - - private bool FunctionExsistsInSymbolInfo(function_node fn, List sil) - { - if (sil != null) - { - foreach (SymbolInfo si in sil) - { - if (si.sym_info is function_node) - if (convertion_data_and_alghoritms.function_eq_params(fn, si.sym_info as function_node)) - return true; - } - } - return false; - } - - internal bool body_exists; - - internal bool current_converted_method_not_in_class_defined = false; - internal bool assign_is_converting = false; - - //lroman// - public void visit_lambda_header(SyntaxTree.function_header _function_header, SyntaxTree.proc_block proc_body) - { - hard_node_test_and_visit(_function_header.name); - if (context.converted_template_type != null) - { - return; - } - if (_function_header.template_args != null) - { - visit_generic_params(context.top_function, _function_header.template_args.idents); - } - SymbolInfo si = context.create_special_names(); - weak_node_test_and_visit(_function_header.parameters); - type_node tn = null; - - #region Вывод типа возвращаемого значения лямбды - - //lroman// - if (LambdaHelper.IsLambdaName(_function_header.name.meth_name)) - { - if (_function_header.return_type != null && _function_header.return_type is SyntaxTree.lambda_inferred_type) - LambdaHelper.InferResultType(_function_header, proc_body, this); - } - //\lroman// - - #endregion - - if (_function_header.return_type == null) - { - if (context.top_function.IsOperator) - AddError(get_location(_function_header), "FUNCTION_NEED_RETURN_TYPE"); - } - if (_function_header.return_type != null) - { - check_parameter_on_complex_type(_function_header.return_type); - tn = convert_strong(_function_header.return_type); - //if (tn == SystemLibrary.SystemLibrary.void_type) - // AddError(new VoidNotValid(get_location(_function_header.return_type))); - check_for_type_allowed(tn,get_location(_function_header.return_type)); - check_using_static_class(tn, get_location(_function_header.return_type)); - } - //(ssyy) moved up, так как при проверке аттрибута override надо знать тип возвращаемого значения - context.top_function.return_value_type = tn; - assign_doc_info(context.top_function,_function_header); - if (_function_header.attributes != null) - { - make_attributes_for_declaration(_function_header, context.top_function); - } - if (context.converted_type != null && has_dll_import_attribute(context.top_function)) - AddError(get_dll_import_attribute(context.top_function).location, "DLLIMPORT_ATTRIBUTE_CANNOT_BE_APPLIED_TO_METHOD"); - if (_function_header.name.class_name != null) - with_class_name = true; - if (_function_header.class_keyword && !has_static_attr(_function_header.proc_attributes.proc_attributes)) - { - SyntaxTree.procedure_attribute pa = new SyntaxTree.procedure_attribute(PascalABCCompiler.SyntaxTree.proc_attribute.attr_static); - pa.source_context = _function_header.source_context; - _function_header.proc_attributes.proc_attributes.Add(pa); - } - weak_node_test_and_visit(_function_header.proc_attributes); - if (context.top_function.IsOperator) - { - common_method_node cmmn = context.top_function as common_method_node; - //if (cmmn == null) - //{ - // throw new OverloadOperatorMustBeStaticFunction(get_location(_function_header), context.top_function); - //} - if (cmmn != null && cmmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - { - AddError(get_location(_function_header), "OVERLOADED_OPERATOR_MUST_BE_STATIC_FUNCTION"); - } - if (cmmn != null && (cmmn.name == compiler_string_consts.implicit_operator_name || cmmn.name == compiler_string_consts.explicit_operator_name)) - if (!convertion_data_and_alghoritms.eq_type_nodes(tn, cmmn.comperehensive_type as type_node) && !convertion_data_and_alghoritms.eq_type_nodes(cmmn.comperehensive_type as type_node, cmmn.parameters[0].type)) - { - AddError(get_location(_function_header.return_type), "RETURN_VALUE_SHOULD_HAVE_TYPE_{0}", (cmmn.comperehensive_type as type_node).PrintableName); - } - else if (convertion_data_and_alghoritms.eq_type_nodes(tn,cmmn.parameters[0].type)) - { - AddError(get_location(_function_header), "CIRCURAL_TYPE_CONVERSION_DEFINITION"); - } - } - with_class_name = false; - if (context.top_function != null && context.top_function is common_namespace_function_node && (context.top_function as common_namespace_function_node).ConnectedToType != null && !context.top_function.IsOperator) - { - concrete_parameter_type cpt = concrete_parameter_type.cpt_none; - SemanticTree.parameter_type pt = PascalABCCompiler.SemanticTree.parameter_type.value; - if ((context.top_function as common_namespace_function_node).ConnectedToType.is_value_type) - { - cpt = concrete_parameter_type.cpt_var; - pt = PascalABCCompiler.SemanticTree.parameter_type.var; - } - if (!has_extensionmethod_attr(_function_header.proc_attributes.proc_attributes)) - { - common_parameter cp = new common_parameter(compiler_string_consts.self_word, (context.top_function as common_namespace_function_node).ConnectedToType, pt, - context.top_function, cpt, null, null); - context.top_function.parameters.AddElementFirst(cp); - context.top_function.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(cp)); - } - } - CheckOverrideOrReintroduceExpectedWarning(get_location(_function_header)); - - bool unique = context.close_function_params(body_exists); - if (context.top_function.return_value_type == null) - AddError(get_location(_function_header), "FUNCTION_NEED_RETURN_TYPE"); - if (_function_header.where_defs != null) - { - if (unique) - { - visit_where_list(_function_header.where_defs); - } - else - { - AddError(get_location(_function_header.where_defs), "WHERE_SECTION_MUST_BE_ONLY_IN_FIRST_DECLARATION"); - } - } - convertion_data_and_alghoritms.create_function_return_variable(context.top_function, si); - - //TODO: Разобрать подробнее. - if (!body_exists) - { - if ((context.top_function.semantic_node_type == semantic_node_type.common_method_node) - || ((context.func_stack_size_is_one()) && (_is_interface_part))) - { - //context.leave_block(); - } - } - body_exists = false; - } - //\lroman// - - public override void visit(SyntaxTree.procedure_definition _procedure_definition) - { - // SSM 20.07.13 если это - узел с коротким определением функции без типа возвращаемого значения, то вывести этот тип - var fh = (_procedure_definition.proc_header as SyntaxTree.function_header); - if (fh != null && fh.return_type == null) - { - var bl = _procedure_definition.proc_body as SyntaxTree.block; - if (bl != null && bl.program_code != null) - { - if (bl.program_code.subnodes.Count != 1) - AddError(get_location(fh.name), "ONLY_IN_SHORT_FUNC_DEFS_RETURN_TYPE_CANBE_OMITTED"); - - var ass = bl.program_code.subnodes[0] as SyntaxTree.assign; - if (ass != null && ass.to is ident && (ass.to as ident).name.ToLower()=="result") - { - if (ass.from is nil_const) - AddError(get_location(ass.from), "CAN_NOT_DEDUCE_TYPE_{0}","nil"); - - // undefined_type означает, что где-то в будущем это надо исправить. Потому что и Result будет этого типа - var typ = new semantic_type_node(new undefined_type("#Und",null));//SyntaxTreeBuilder.BuildSameType(ass.from); - fh.return_type = typ; - } - else AddError(get_location(fh.name), "ONLY_IN_SHORT_FUNC_DEFS_RETURN_TYPE_CANBE_OMITTED"); - } - } - //\ SSM - - var proc_name = _procedure_definition.proc_header != null && _procedure_definition.proc_header.name != null - ? _procedure_definition.proc_header.name.meth_name - : null; - if (_procedure_definition.proc_header.attributes != null && context.converted_func_stack.size >= 1) - AddError(get_location(_procedure_definition.proc_header), "ATTRIBUTES_FOR_NESTED_FUNCTIONS_NOT_ALLOWED"); - if (context.top_function != null && context.top_function.generic_params != null && !LambdaHelper.IsLambdaName(proc_name) && !(_procedure_definition.proc_header is SyntaxTree.constructor)) - AddError(get_location(_procedure_definition.proc_header), "NESTED_FUNCTIONS_IN_GENERIC_FUNCTIONS_NOT_ALLOWED"); - if (context.top_function != null && _procedure_definition.proc_header.template_args != null && !LambdaHelper.IsLambdaName(proc_name)) - AddError(get_location(_procedure_definition.proc_header), "GENERIC_NESTED_FUNCTIONS_NOT_ALLOWED"); - if (_procedure_definition.proc_header.name != null) - current_converted_method_not_in_class_defined = _procedure_definition.proc_header.name.class_name != null; - else - { - if (_procedure_definition.proc_header is SyntaxTree.constructor) - { - current_converted_method_not_in_class_defined = false; - } - } - bool must_visit_body = true; - if (SemanticRules.OrderIndependedMethodNames && !disable_order_independ && context.converting_block() == block_type.type_block && _procedure_definition.proc_body != null) - { - if (_procedure_definition.proc_header.name != null) - { - if (_procedure_definition.proc_header.name.class_name == null || _procedure_definition.Parent is class_members) // SSM #2173 01/07/20 - добавка после || - озн, что это явное расширение интерфейса - { - must_visit_body = false; - context.is_order_independed_method_description = true; - } - } - else - { - must_visit_body = false; - context.is_order_independed_method_description = true; - } - } - if (SemanticRules.OrderIndependedFunctionNames && !disable_order_independ && context.converting_block() == block_type.namespace_block && _procedure_definition.proc_body != null && _procedure_definition.proc_header.name.class_name == null) - { - if (_procedure_definition.proc_header.name != null) - { - if (_procedure_definition.proc_header.name.class_name == null) - { - must_visit_body = false; - context.is_order_independed_method_description = true; - } - } - else - { - must_visit_body = false; - context.is_order_independed_method_description = true; - } - } - //ssyy - if (context.converting_block() == block_type.type_block && - context.converted_type.IsInterface) - { - AddError(get_location(_procedure_definition), "INVALID_INTERFACE_MEMBER"); - } - //\ssyy - - //ssyy добавил - if (context.converting_block() == block_type.function_block) - { - common_method_node cmnode = context.top_function as common_method_node; - if (cmnode != null && cmnode.is_constructor) - { - //throw new NotSupportedError(get_location(_procedure_definition)); - } - } - //\ssyy - if (context.converted_type != null && context.converted_type.IsStatic && !_procedure_definition.proc_header.class_keyword) - AddError(get_location(_procedure_definition), "STATIC_CLASSES_CANNOT_NON_STATIC_MEMBERS"); - if (_procedure_definition.proc_body == null) - { - body_exists = false; - } - else - { - body_exists = true; - } - - //lroman// - if (_procedure_definition != null && - _procedure_definition.proc_header != null && - _procedure_definition.proc_header is SyntaxTree.function_header && - _procedure_definition.proc_header.name != null && - _procedure_definition.proc_header.name.meth_name != null && - LambdaHelper.IsLambdaName(_procedure_definition.proc_header.name.meth_name)) - { - //!!!!!!!!!!!!!!!!!! - convertion_data_and_alghoritms.check_node_parser_error(_procedure_definition.proc_header); - visit_lambda_header(_procedure_definition.proc_header as SyntaxTree.function_header, _procedure_definition.proc_body); - } - else - { - hard_node_test_and_visit(_procedure_definition.proc_header); - } - //\lroman// - - - // Patterns - - if (context.top_function != null && - context.top_function is common_namespace_function_node commonNode && - commonNode.name.ToLower() == compiler_string_consts.deconstruct_method_name) - { - var deconstructor = commonNode; - - if (!deconstructor.is_extension_method) - { - //AddWarning(); - } - else - { - if (deconstructor.is_generic_function && - deconstructor.generic_parameters_count != GenericParameterIndices(GetSelfParameter(deconstructor).type).Count()) - AddError(get_location(_procedure_definition), "DECONSTRUCTOR_GENERIC_PARAMETERS_SHOULD_BE_DEFINED_BY_SELF_PARAMETER"); - - ExecuteCommonChecks(deconstructor); - } - } - - if (context.top_function != null && - context.top_function is common_method_node methodNode && - methodNode.name.ToLower() == compiler_string_consts.deconstruct_method_name) - { - var deconstructor = methodNode; - - if (deconstructor.is_generic_function) - AddError(get_location(_procedure_definition), "INSTANCE_DECONSTRUCTORS_CANNOT_BE_GENERIC"); - - ExecuteCommonChecks(deconstructor); - } - - // !Patterns - - //ssyy - if (context.converted_template_type != null) - { - if ((context.converted_template_type.type_dec.type_def as SyntaxTree.class_definition).keyword == PascalABCCompiler.SyntaxTree.class_keyword.Interface) - { - AddError(new InterfaceFunctionWithBody(get_location(_procedure_definition))); - } - context.converted_template_type.external_methods.Add( - new procedure_definition_info(context.converted_namespace, _procedure_definition)); - context.converted_template_type = null; - return; - } - //\ssyy - if (context.top_function == null) - { - return; - } - - // frninja 20/05/16 - ставим флаг is_yield_helper - if (context.top_function is common_namespace_function_node) - { - (context.top_function as common_namespace_function_node).is_yield_helper = _procedure_definition.proc_header.is_yield_helper; - } - // end frninja - - if (context.converted_explicit_interface_type != null) - (context.top_function as common_method_node).explicit_interface = context.converted_explicit_interface_type; - if (has_dll_import_attribute(context.top_function)) - { - if (_procedure_definition.proc_body != null) - if (!is_pinvoke(_procedure_definition.proc_body)) - AddError(get_location(_procedure_definition.proc_body), "EXPECTED_EXTERNAL_STATEMENT"); - must_visit_body = true; - } - - if (contextChanger.IsActive()) - { - must_visit_body = true; - } - - if (context.top_function.return_value_type is undefined_type) // значит, это короткое определение функции, и тело есть, и его надо обойти - { - must_visit_body = true; - } - - // try - { - - if (context.top_function.is_forward) - { - if (_procedure_definition.proc_body != null) - { - AddError(context.top_function.loc, "FORWARD_DEFINITION_WITH_FUNCTION_BODY"); - } - } - else - { - if (must_visit_body) - { - common_method_node cmn = context.top_function as common_method_node; - - // frninja 3/06/16 - ставим флаг is_yield_helper для предописанных методов класса - if (cmn != null) - cmn.is_yield_helper = _procedure_definition.proc_header.is_yield_helper; - // end frninja - - if (cmn != null && !cmn.IsStatic) - { - //if (cmn.find_only_in_namespace(compiler_string_consts.self_word) == null) - //self variable - //добавляем self, обращение к ней заменяется на this_node - type_node self_type = cmn.cont_type; - if (cmn.cont_type.is_generic_type_definition) - self_type = cmn.cont_type.get_instance(cmn.cont_type.generic_params.ConvertAll(o => (type_node)o)); - local_variable lv = new local_variable(compiler_string_consts.self_word, self_type, cmn, null); - cmn.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv)); - cmn.self_variable = lv; - } - if (_procedure_definition.proc_body != null) - { - hard_node_test_and_visit(_procedure_definition.proc_body); - } - - // SSM 12/04/16 - short func definitions - calc return_value_type - var ttt = context.top_function.return_value_type; - if (ttt is undefined_type) - { - var cd = context.top_function.function_code as statements_list; - - if (cd == null || cd.statements == null || cd.statements.Count == 0) - { - AddError(context.top_function.loc, "IMPOSSIBLE!SHORT_FUNC_WITHOUT_BODY"); - } - - // Проблема в том, что если в теле короткого определения функции - лямбда - // и происходит захват переменной, то в тело выносится вызов конструктора сгенерированного класса - // Поэтому result := ... - это не первый оператор, а последний!!! - statement_node aa = cd.statements[cd.statements.Count-1]; - var bfc = aa as basic_function_call; - if (bfc != null) - { - var ttt1 = bfc.type; - context.top_function.return_value_type = ttt1; - context.top_function.var_definition_nodes_list[0].type = ttt1; - } - } - - add_clip_for_set(context.top_function); - } - else // if (!must_visit_body) - { - context.add_method_header(_procedure_definition, context.top_function); - } - - } - } - //finally - { - if (_procedure_definition.proc_header.name.class_name != null) - { - // frninja 03/06/16 - убираем мусорные методы-хелперы yield - if (context._ctn != null && (context.top_function is common_method_node) && (context.top_function as common_method_node).is_yield_helper) - { - context._ctn.methods.remove(context.top_function as common_method_node); - } - // end frninja - context.leave_type_method(); - } - /*else - { - if (context._cmn != null && context._cmn.functions != null && (context.top_function is common_namespace_function_node) && - (context.top_function as common_namespace_function_node).is_yield_helper && - context.top_function.name.ToLower().StartsWith(" attrs) - { - foreach (SyntaxTree.procedure_attribute attr in attrs) - { - if (attr.attribute_type == PascalABCCompiler.SyntaxTree.proc_attribute.attr_static) - { - return true; - } - } - return false; - } - - bool has_extensionmethod_attr(List attrs) - { - foreach (SyntaxTree.procedure_attribute attr in attrs) - { - if (attr.attribute_type == PascalABCCompiler.SyntaxTree.proc_attribute.attr_extension) - { - return true; - } - } - return false; - } - - private bool has_var_char_parameters(common_function_node fn) - { - for (int i=0; i p.idents.idents).Where(id => id.name.ToLower() == "self"); - if (q != null && q.Count() > 0) - { - var sid = q.First(); - AddError(get_location(sid), "SELF_NOT_ALLOWED_IN_METHOD_PARAMS"); - } - } - - current_function_header = null; - if (context.converted_template_type != null) - { - return; - } - if (_procedure_header.template_args != null) - { - visit_generic_params(context.top_function, _procedure_header.template_args.idents); - } - if (_procedure_header.where_defs != null) - { - visit_where_list(_procedure_header.where_defs); - } - weak_node_test_and_visit(_procedure_header.parameters); - if (_procedure_header.name.class_name != null) - with_class_name = true; - if (_procedure_header.class_keyword && !has_static_attr(_procedure_header.proc_attributes.proc_attributes)) - { - SyntaxTree.procedure_attribute pa = new SyntaxTree.procedure_attribute(PascalABCCompiler.SyntaxTree.proc_attribute.attr_static); - pa.source_context = _procedure_header.source_context; - _procedure_header.proc_attributes.proc_attributes.Insert(0, pa); - } - weak_node_test_and_visit(_procedure_header.proc_attributes); - with_class_name = false; - CheckOverrideOrReintroduceExpectedWarning(get_location(_procedure_header)); - if (context.top_function != null && context.top_function is common_namespace_function_node && (context.top_function as common_namespace_function_node).ConnectedToType != null && !context.top_function.IsOperator) - { - concrete_parameter_type cpt = concrete_parameter_type.cpt_none; - SemanticTree.parameter_type pt = PascalABCCompiler.SemanticTree.parameter_type.value; - if ((context.top_function as common_namespace_function_node).ConnectedToType.is_value_type) - { - cpt = concrete_parameter_type.cpt_var; - pt = PascalABCCompiler.SemanticTree.parameter_type.var; - } - type_node cur_tn = (context.top_function as common_namespace_function_node).ConnectedToType; - type_node self_type = cur_tn; - if (context.top_function.generic_params != null && self_type.is_generic_type_definition) - { - self_type = self_type.get_instance(context.top_function.get_generic_params_list()); - } - if (!has_extensionmethod_attr(_procedure_header.proc_attributes.proc_attributes)) - { - common_parameter cp = new common_parameter(compiler_string_consts.self_word, self_type, pt, - context.top_function, cpt, null, null); - - context.top_function.parameters.AddElementFirst(cp); - context.top_function.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(cp)); - } - } - - if (_procedure_header is SyntaxTree.constructor) - { - common_method_node cmnode = context.top_function as common_method_node; - if (cmnode != null) - { - cmnode.is_constructor = true; - cmnode.return_value_type = context.converted_type; - - } - else if (context.top_function is common_namespace_function_node && (context.top_function as common_namespace_function_node).ConnectedToType != null) - AddError(get_location(_procedure_header), "EXTENSION_CONSTRUCTOR_NOT_ALLOWED"); - else - if (context.converted_compiled_type != null) - AddError(get_location(_procedure_header), "EXTENSION_CONSTRUCTOR_NOT_ALLOWED"); - } - - if (context.top_function.IsOperator) - { - if (context.top_function is common_method_node) - { - common_method_node cmmn = context.top_function as common_method_node; - if (cmmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - { - AddError(get_location(_procedure_header), "OVERLOADED_OPERATOR_MUST_BE_STATIC_FUNCTION"); - } - } - } - bool unique = context.close_function_params(body_exists); - - if (context.converted_type != null && context.converted_type.IsInterface) - { - if (body_exists) - { - AddError(new InterfaceFunctionWithBody(get_location(_procedure_header))); - } - common_method_node cmnode = context.top_function as common_method_node; - context.set_virtual_abstract(cmnode); - } - - if (context.converted_type != null) - { - common_method_node cmnode = context.top_function as common_method_node; - if (cmnode != null && cmnode.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract && body_exists) - { - AddError(new AbstractMethodWithBody(get_location(_procedure_header))); - } - } - if (_procedure_header.where_defs != null) - { - if (!unique && false) - { - AddError(get_location(_procedure_header.where_defs), "WHERE_SECTION_MUST_BE_ONLY_IN_FIRST_DECLARATION"); - } - } - assign_doc_info(context.top_function,_procedure_header); - if (_procedure_header.attributes != null) - { - make_attributes_for_declaration(_procedure_header, context.top_function); - } - if (context.converted_type != null && has_dll_import_attribute(context.top_function)) - AddError(get_dll_import_attribute(context.top_function).location, "DLLIMPORT_ATTRIBUTE_CANNOT_BE_APPLIED_TO_METHOD"); - if (!body_exists) - { - if (_procedure_header.name.class_name != null && context.converted_explicit_interface_type != null) - { - AddError(get_location(_procedure_header), "EXPLICIT_IMPLEMENTATION_EXPECTED"); - } - if ((context.top_function.semantic_node_type == semantic_node_type.common_method_node) - || ((context.func_stack_size_is_one()) && (_is_interface_part))) - { - context.leave_block(); - if (_procedure_header.name.class_name != null && context.converted_compiled_type != null) - context.converted_compiled_type = null; - } - } - body_exists = false; - - } - - public override void visit(SyntaxTree.procedure_header _procedure_header) - { - visit_procedure_header(_procedure_header); - } - - public override void visit(SyntaxTree.procedure_attributes_list _procedure_attributes_list) - { - bool is_override = false; - bool is_virtual = false; - bool is_abstract = false; - string override_proc_attr=null; - string virtual_proc_attr=null; - string abstract_proc_attr = null; - for (int i = 0; i < _procedure_attributes_list.proc_attributes.Count; i++) - { - switch (_procedure_attributes_list.proc_attributes[i].attribute_type) - { - case SyntaxTree.proc_attribute.attr_abstract: - { - is_abstract = true; - abstract_proc_attr = _procedure_attributes_list.proc_attributes[i].name; - } - break; - case SyntaxTree.proc_attribute.attr_override: - { - is_override = true; - override_proc_attr = _procedure_attributes_list.proc_attributes[i].name; - } - break; - case SyntaxTree.proc_attribute.attr_virtual: - { - is_virtual = true; - virtual_proc_attr = _procedure_attributes_list.proc_attributes[i].name; - } - break; - } - } - context.top_function.is_overload = true; // SSM 12/08/15 - context.last_created_function.symbol_kind = symbol_kind.sk_overload_function; - bool is_forward = false; - for (int i = 0; i < _procedure_attributes_list.proc_attributes.Count; i++) - { - convertion_data_and_alghoritms.check_node_parser_error(_procedure_attributes_list.proc_attributes[i]); - for (int j = 0; j < i; j++) - { - if (_procedure_attributes_list.proc_attributes[i].attribute_type == - _procedure_attributes_list.proc_attributes[j].attribute_type) - { - AddError(new DuplicateAttributeDefinition(get_location(_procedure_attributes_list.proc_attributes[j]), - get_location(_procedure_attributes_list.proc_attributes[i]))); - } - } - - switch (_procedure_attributes_list.proc_attributes[i].attribute_type) - { - case SyntaxTree.proc_attribute.attr_overload:// ничего не делать - это и так есть - { - break; - } - case SyntaxTree.proc_attribute.attr_forward: - { - if (with_class_name) - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "DIRECTIVE_{0}_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name); - //(ssyy) В интерфейсах аттрибуты недопустимы - if (context.converted_type != null && context.converted_type.IsInterface) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "ATTRIBUTES_IN_INTERFACE_MEMBER"); - } - common_namespace_function_node top_function = context.top_function as common_namespace_function_node; - if (top_function != null && top_function.ConnectedToType != null) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "FORWARD_EXTENSION_METHODS_NOT_ALLOWED"); - } - - is_forward = true; - break; - } - case SyntaxTree.proc_attribute.attr_virtual: - { - - if (with_class_name) - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "DIRECTIVE_{0}_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name); - //(ssyy) В интерфейсах аттрибуты недопустимы - if (context.converted_type != null && context.converted_type.IsInterface) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "ATTRIBUTES_IN_INTERFACE_MEMBER"); - } - - //(ssyy) В записях нет виртуальных функций - if (context.converted_type != null && context.converted_type.is_value) - { - AddError(new VirtualMethodInRecord( - get_location(_procedure_attributes_list.proc_attributes[i]))); - } - - common_function_node ccfn = context.top_function; - if (ccfn.semantic_node_type != semantic_node_type.common_method_node) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "{0}_KEYWORD_ALLOWED_ONLY_WITH_METHOD", _procedure_attributes_list.proc_attributes[i].name); - } - common_method_node cmn = ccfn as common_method_node; - if (cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "CAN_NOT_BE_VIRTUAL_STATIC_METHOD"); - } - if (is_override) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "USING_MODIFIERS{0}_{1}_TOGETHER_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name,override_proc_attr); - } - if (!context.converted_type.IsAbstract || true) - { - is_virtual = true; - virtual_proc_attr = _procedure_attributes_list.proc_attributes[i].name; - if (!is_abstract) - context.set_virtual(cmn); - } - break; - } - case SyntaxTree.proc_attribute.attr_override: - case SyntaxTree.proc_attribute.attr_reintroduce: - { - if (with_class_name) - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "DIRECTIVE_{0}_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name); - //(ssyy) В интерфейсах аттрибуты недопустимы - if (context.converted_type != null && context.converted_type.IsInterface) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "ATTRIBUTES_IN_INTERFACE_MEMBER"); - } - - common_function_node ccfn = context.top_function; - if (ccfn.return_value_type is undefined_type) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "OVERRIDE_NOT_ALLOWED_FOR_SHORT_FUNCTIONS"); - } - if (ccfn.semantic_node_type != semantic_node_type.common_method_node) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "{0}_KEYWORD_ALLOWED_ONLY_WITH_METHOD", _procedure_attributes_list.proc_attributes[i].name); - } - common_method_node cmn = ccfn as common_method_node; - if (cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "CAN_NOT_BE_VIRTUAL_STATIC_METHOD"); - } - if (_procedure_attributes_list.proc_attributes[i].attribute_type == SyntaxTree.proc_attribute.attr_reintroduce) - { - cmn.IsReintroduce = true; - if (is_abstract) - cmn.newslot_awaited = true; - break; - } - if (_procedure_attributes_list.proc_attributes[i].attribute_type == SyntaxTree.proc_attribute.attr_override && is_virtual) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]),"USING_MODIFIERS{0}_{1}_TOGETHER_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name,virtual_proc_attr); - } - if (_procedure_attributes_list.proc_attributes[i].attribute_type == SyntaxTree.proc_attribute.attr_override) - { - is_override = true; - override_proc_attr = _procedure_attributes_list.proc_attributes[i].name; - } - - context.set_override(cmn); - if (is_abstract) - { - cmn.polymorphic_state = SemanticTree.polymorphic_state.ps_virtual_abstract; - - } - if (is_override && _procedure_attributes_list.Parent is procedure_header ph && ph.where_defs != null) - AddError(cmn.loc, "OVERRIDE_METHODS_CANNOT_CONTAIN_WHERE_SECTION"); - - if (cmn.field_access_level < cmn.overrided_method.field_access_level) - AddError(cmn.loc, "CAN_NOT_BE_DOWN_ACCESS_LEVEL_FOR_METH"); - break; - } - case SyntaxTree.proc_attribute.attr_static: - { - if (with_class_name) - { - if (context.top_function != null) - { - context.top_function.polymorphic_state = PascalABCCompiler.SemanticTree.polymorphic_state.ps_static; - break; - } - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "DIRECTIVE_{0}_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name); - } - //(ssyy) В интерфейсах аттрибуты недопустимы - if (context.converted_type != null && context.converted_type.IsInterface) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "ATTRIBUTES_IN_INTERFACE_MEMBER"); - } - - common_function_node ccfn = context.top_function; - if (ccfn.semantic_node_type != semantic_node_type.common_method_node) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "STATIC_KEYWORD_ALLOWED_ONLY_WITH_METHOD"); - } - common_method_node cmn = ccfn as common_method_node; - if (cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "CAN_NOT_BE_VIRTUAL_STATIC_METHOD"); - } - if (cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "CANNOT_BE_ABSTRACT_STATIC_METHOD"); - } - cmn.polymorphic_state = SemanticTree.polymorphic_state.ps_static; - break; - } - case SyntaxTree.proc_attribute.attr_abstract: - { - if (with_class_name) - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "DIRECTIVE_{0}_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name); - if (context.converted_type != null && context.converted_type.IsInterface) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "ATTRIBUTES_IN_INTERFACE_MEMBER"); - } - common_function_node ccfn = context.top_function; - common_method_node cmn = ccfn as common_method_node; - - if (ccfn.semantic_node_type != semantic_node_type.common_method_node) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "{0}_KEYWORD_ALLOWED_ONLY_WITH_METHOD", _procedure_attributes_list.proc_attributes[i].name); - } - if (context.converted_type != null && context.converted_type.is_value) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "ABSTRACT_METHOD_IN_RECORD"); - } - if (ccfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "CANNOT_BE_ABSTRACT_STATIC_METHOD"); - } - if (cmn.is_constructor) - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "DIRECTIVE_{0}_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name); - cmn.polymorphic_state = SemanticTree.polymorphic_state.ps_virtual_abstract; - if (context.converted_type.IsSealed) - AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "ABSTRACT_METHOD_IN_SEALED_CLASS"); - context.converted_type.SetIsAbstract(true); - if (cmn.IsReintroduce) - cmn.newslot_awaited = true; - break; - } - case proc_attribute.attr_extension: - { - if (is_forward) - AddError(get_location(_procedure_attributes_list), "EXTENSIONMETHOD_KEYWORD_NOT_ALLOWED"); - if (context.converted_compiled_type != null) - AddError(get_location(_procedure_attributes_list), "EXTENSIONMETHOD_KEYWORD_NOT_ALLOWED"); - if (in_interface_part) - AddError(get_location(_procedure_attributes_list), "EXTENSION_METHODS_IN_INTERFACE_PART_NOT_ALLOWED"); - if (!(context.top_function is common_namespace_function_node)) - AddError(get_location(_procedure_attributes_list), "EXTENSION_ATTRIBUTE_ONLY_FOR_NAMESPACE_FUNCTIONS_ALLOWED"); - if (context.top_function.parameters.Count == 0) - AddError(context.top_function.loc, "EXTENSION_METHODS_MUST_HAVE_LEAST_ONE_PARAMETER"); - if (!context.top_function.IsOperator && context.top_function.parameters[0].parameter_type != SemanticTree.parameter_type.value - && !(context.top_function.parameters[0].type is compiled_type_node ctn && ctn.compiled_type == typeof(string))) - AddError(context.top_function.loc, "FIRST_PARAMETER_SHOULDBE_ONLY_VALUE_PARAMETER"); - if (!context.top_function.IsOperator && context.top_function.parameters[0].name.ToLower() != compiler_string_consts.self_word) - AddError(context.top_function.loc,"FIRST_PARAMETER_MUST_HAVE_NAME_SELF"); - - common_namespace_function_node top_function = context.top_function as common_namespace_function_node; - top_function.ConnectedToType = context.top_function.parameters[0].type; - if (top_function.ConnectedToType.Scope == null && top_function.ConnectedToType is compiled_type_node) - { - (top_function.ConnectedToType as compiled_type_node).init_scope(); - } - if (top_function.ConnectedToType.Scope == null) - AddError(context.top_function.loc, "EXTENSION_METHODS_FOR_CONSTRUCTED_TYPES_NOT_ALLOWED"); - SymbolInfo si = new SymbolInfo(context.top_function); - si.symbol_kind = symbol_kind.sk_overload_function; - top_function.ConnectedToType.Scope.AddSymbol(top_function.name, si); - if (top_function.ConnectedToType.type_special_kind == SemanticTree.type_special_kind.array_kind /*&& top_function.ConnectedToType.element_type.is_generic_parameter*/) - top_function.ConnectedToType.base_type.Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function)); - else if (top_function.ConnectedToType.is_generic_parameter) - top_function.ConnectedToType.base_type.Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function)); - else if (top_function.ConnectedToType is compiled_type_node && top_function.ConnectedToType.is_generic_type_instance && top_function.ConnectedToType.original_generic.Scope != null) - top_function.ConnectedToType.original_generic.Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function)); - else if (top_function.ConnectedToType is compiled_generic_instance_type_node && top_function.ConnectedToType.original_generic.Scope != null) - top_function.ConnectedToType.original_generic.Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function)); - else if (top_function.ConnectedToType.IsDelegate && top_function.ConnectedToType.base_type.IsDelegate) - compiled_type_node.get_type_node(typeof(Delegate)).Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function)); - else if (top_function.ConnectedToType.type_special_kind == SemanticTree.type_special_kind.typed_file && top_function.ConnectedToType.element_type.is_generic_parameter && SystemLibrary.SystemLibInitializer.TypedFileType.sym_info != null) - (SystemLibrary.SystemLibInitializer.TypedFileType.sym_info as type_node).Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function)); - if (top_function.ConnectedToType.IsDelegate && context.top_function.IsOperator && (context.top_function.name == "+" || context.top_function.name == "-" || context.top_function.name == "+=" || context.top_function.name == "-=")) - AddError(get_location(_procedure_attributes_list), "CANNOT_EXTEND_STANDARD_OPERATORS_FOR_DELEGATE"); - if (context.top_function.IsOperator && (context.top_function.name == compiler_string_consts.implicit_operator_name || context.top_function.name == compiler_string_consts.explicit_operator_name) && context.top_function.parameters.Count == 1 && context.top_function.return_value_type != null) - { - if (!(context.top_function.return_value_type is compiled_type_node) && !(context.top_function.return_value_type is compiled_generic_instance_type_node) || !(context.top_function.parameters[0].type is compiled_type_node) && !(context.top_function.parameters[0].type is compiled_generic_instance_type_node)) - ;//AddError(get_location(_procedure_attributes_list), "IMPLICIT_EXPLICIT_OPERATOR_EXTENSION_ONLY_FOR_COMPILED_CLASSES_ALLOWED"); - } - break; - } - default: - { - throw new NotSupportedError(get_location(_procedure_attributes_list.proc_attributes[i])); - } - } - } - } - - private bool first_param=false; - public override void visit(SyntaxTree.formal_parameters _formal_parametres) - { - bool default_value_met = false; - bool params_met = false; - first_param = true; - foreach (SyntaxTree.typed_parameters tp in _formal_parametres.params_list) - { - if (params_met) - { - AddError(get_location(tp), "ONLY_LAST_PARAMETER_CAN_BE_PARAMS"); - } - if (tp.param_kind == PascalABCCompiler.SyntaxTree.parametr_kind.params_parametr) - { - params_met = true; - if (default_value_met) - { - AddError(get_location(tp), "FUNCTION_WITH_PARAMS_PARAMETER_CAN_NOT_HAVE_DEFAULT_PARAMETERS"); - } - } - hard_node_test_and_visit(tp); - first_param = false; - if ((default_value_met) && (tp.inital_value == null)) - { - AddError(new NeedDefaultValueForParameter(get_location(tp))); - } - - if (tp.inital_value != null) - { - default_value_met = true; - } - } - first_param = false; - common_method_node cnode = context.top_function as common_method_node; - parameter_list pars = context.top_function.parameters; - if (cnode != null && cnode.IsOperator) - { - - if (cnode.name != compiler_string_consts.implicit_operator_name && cnode.name != compiler_string_consts.explicit_operator_name) - { - bool all_types_mismatch = true; - foreach (parameter par in pars) - { - //if (par.type == cnode.comperehensive_type) - if (convertion_data_and_alghoritms.eq_type_nodes(par.type, cnode.comperehensive_type as type_node)) - { - all_types_mismatch = false; - break; - } - } - if (all_types_mismatch) - { - AddError(cnode.loc, "TYPE_OF_ONE_OR_MORE_OPERATOR_PARAMETERS_MUST_BE_{0}", ((type_node)(cnode.comperehensive_type)).PrintableName); - } - } - if (pars.Count > 0 && pars[pars.Count - 1].is_params) - { - AddError(convertion_data_and_alghoritms.get_location(pars[pars.Count - 1]), "PARAMS_IN_OPERATOR"); - } - - } - if (context.top_function.IsOperator) - { - int pcount = name_reflector.get_params_count(context.top_function.name); - if (pcount != pars.Count) - { - if (context.top_function.name != compiler_string_consts.minus_name && context.top_function.name != compiler_string_consts.plus_name) - AddError(context.top_function.loc, "OPERATOR_{0}_PARAMETERS_COUNT_MUST_EQUAL_{1}", context.top_function.name, pcount); - else - if (pars.Count != 1 && pars.Count != 2) - AddError(context.top_function.loc, "OPERATOR_{0}_PARAMETERS_COUNT_MUST_EQUAL_{1}", context.top_function.name, pcount); - } - } - } - - private void check_array_on_complex_type(SyntaxTree.array_type type) - { - SyntaxTree.array_type arr = type as SyntaxTree.array_type; - if (arr.indexers != null && arr.indexers.indexers.Count > 0 && arr.indexers.indexers[0] != null) - AddError(get_location(type), "STRUCT_TYPE_DEFINITION_IN_FORMAL_PARAM"); - if (arr.elements_type is SyntaxTree.array_type) - check_array_on_complex_type(arr.elements_type as SyntaxTree.array_type); - else if (arr.elements_type is SyntaxTree.class_definition) - AddError(get_location(arr.elements_type), "STRUCT_TYPE_DEFINITION_IN_FORMAL_PARAM"); - else if (arr.elements_type is SyntaxTree.set_type_definition) - check_set_on_complex_type(arr.elements_type as set_type_definition); - else if (arr.elements_type is SyntaxTree.file_type) - check_file_on_complex_type(arr.elements_type as file_type); - } - - private void check_set_on_complex_type(SyntaxTree.set_type_definition type) - { - SyntaxTree.set_type_definition set = type as SyntaxTree.set_type_definition; - if (set.of_type is SyntaxTree.array_type) - check_array_on_complex_type(set.of_type as SyntaxTree.array_type); - else if (set.of_type is SyntaxTree.class_definition) - AddError(get_location(set.of_type), "STRUCT_TYPE_DEFINITION_IN_FORMAL_PARAM"); - else if (set.of_type is SyntaxTree.file_type) - check_file_on_complex_type(set.of_type as file_type); - else if (set.of_type is SyntaxTree.set_type_definition) - check_set_on_complex_type(set.of_type as set_type_definition); - } - - private void check_file_on_complex_type(SyntaxTree.file_type type) - { - SyntaxTree.file_type file = type as SyntaxTree.file_type; - if (file.file_of_type is SyntaxTree.array_type) - check_array_on_complex_type(file.file_of_type as SyntaxTree.array_type); - else if (file.file_of_type is SyntaxTree.class_definition) - AddError(get_location(file.file_of_type), "STRUCT_TYPE_DEFINITION_IN_FORMAL_PARAM"); - else if (file.file_of_type is SyntaxTree.file_type) - check_file_on_complex_type(file.file_of_type as file_type); - else if (file.file_of_type is SyntaxTree.set_type_definition) - check_set_on_complex_type(file.file_of_type as set_type_definition); - } - - public void check_parameter_on_complex_type(SyntaxTree.type_definition type) - { - SyntaxTree.array_type arr = type as SyntaxTree.array_type; - if (type is SyntaxTree.class_definition || /*type is SyntaxTree.enum_type_definition ||*/ - (arr != null && arr.indexers != null && arr.indexers.indexers.Count > 0 && arr.indexers.indexers[0] != null)) - { - AddError(get_location(type), "STRUCT_TYPE_DEFINITION_IN_FORMAL_PARAM"); - } - if (arr != null) - { - check_array_on_complex_type(arr); - return; - } - if (type is SyntaxTree.set_type_definition) - { - check_set_on_complex_type(type as SyntaxTree.set_type_definition); - return; - } - else if (type is SyntaxTree.file_type) - { - check_file_on_complex_type(type as SyntaxTree.file_type); - return; - } - if (context.top_function is common_method_node && (context.converted_type.IsInterface || context.top_function.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract ) - && (type is function_header || type is procedure_header)) - AddError(get_location(type), "ANONYMOUS_DELEGATE_IN_INTERFACE_NOT_ALLOWED"); - } - - public override void visit(SyntaxTree.typed_parameters _typed_parametres) - { - SemanticTree.parameter_type par_type = SemanticTree.parameter_type.value; - concrete_parameter_type cpt = concrete_parameter_type.cpt_none; - bool is_params = false; - switch (_typed_parametres.param_kind) - { - case SyntaxTree.parametr_kind.const_parametr: - { - par_type = SemanticTree.parameter_type.value; - cpt = concrete_parameter_type.cpt_const; - break; - } - case SyntaxTree.parametr_kind.none: - { - par_type = SemanticTree.parameter_type.value; - cpt = concrete_parameter_type.cpt_none; - break; - } - case SyntaxTree.parametr_kind.out_parametr: - { - par_type = SemanticTree.parameter_type.var; - cpt = concrete_parameter_type.cpt_var; - break; - } - case SyntaxTree.parametr_kind.var_parametr: - { - par_type = SemanticTree.parameter_type.var; - cpt = concrete_parameter_type.cpt_var; - break; - } - case PascalABCCompiler.SyntaxTree.parametr_kind.params_parametr: - { - is_params = true; - break; - } - } - common_parameter com_par = null; - if (is_params) - { - if (_typed_parametres.idents.idents.Count != 1) - { - AddError(get_location(_typed_parametres.idents.idents[1]), "ONLY_ONE_PARAMS_PARAMETER_ALLOWED"); - } - } - foreach (SyntaxTree.ident id in _typed_parametres.idents.idents) - { - com_par = context.add_parameter(id.name, par_type, cpt, get_location(id)); - if (is_params) - { - com_par.intrenal_is_params = true; - } - } - - if (_typed_parametres.vars_type == null) - throw new NotSupportedError(get_location(_typed_parametres)); - - check_parameter_on_complex_type(_typed_parametres.vars_type); - type_node tn = convert_strong(_typed_parametres.vars_type); - if (tn.IsStatic) - AddError(get_location(_typed_parametres), "VARIABLES_OF_STATIC_CLASS_NOT_ALLOWED"); - if (_typed_parametres.vars_type is function_header || _typed_parametres.vars_type is procedure_header) - { - check_delegate_on_generic_parameters(tn as common_type_node, get_location(_typed_parametres.vars_type)); - } - check_for_type_allowed(tn,get_location(_typed_parametres.vars_type)); - if (is_params) - { - internal_interface ii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface); - if (ii == null) - { - AddError(get_location(_typed_parametres.vars_type), "ONLY_UNSIZED_ARRAY_PARAMS_PARAMETER_ALLOWED"); - } - } - com_par.type = tn; - foreach (SyntaxTree.ident id in _typed_parametres.idents.idents) - { - if (_typed_parametres.attributes != null) - { - make_attributes_for_declaration(_typed_parametres, com_par); - } - - } - com_par.type = tn; - context.in_parameters_block = true; - - //TODO: Доделать параметры со значениями по умолчанию. - if (_typed_parametres.inital_value != null) - { - if (_typed_parametres.idents.idents.Count != 1) - { - AddError(new OnlyOneParameterNameWithDefaultValueAllowed(get_location(_typed_parametres))); - } - if (cpt == concrete_parameter_type.cpt_var) - { - AddError(new VarParametersCanNotHaveDefaultValue(get_location(_typed_parametres))); - } - if (cpt == concrete_parameter_type.cpt_const) - { - AddError(get_location(_typed_parametres), "CONST_PARAMETERS_CANNOT_HAVE_DEFAULT_VALUE"); - } - context.top_function.num_of_default_variables = context.top_function.num_of_default_variables + 1; - expression_node def_val_expr = convert_strong_to_constant_node(_typed_parametres.inital_value); - com_par.default_value = convertion_data_and_alghoritms.convert_type(def_val_expr, tn); - } - context.in_parameters_block = false; - context.close_var_definition_list(tn, null); - } - - private void check_delegate_on_generic_parameters(common_type_node ctn, location loc) - { - if (ctn == null) - return; - foreach (common_method_node cmn in ctn.methods) - { - if (cmn.name == "Invoke") - { - foreach (common_parameter prm in cmn.parameters) - { - if (is_instance_of_generic_parameter(prm.type)) - AddError(loc, "ANONYMOUS_FUNCTION_TYPE_WITH_GENERICS"); - } - if (cmn.return_value_type != null && is_instance_of_generic_parameter(cmn.return_value_type)) - AddError(loc, "ANONYMOUS_FUNCTION_TYPE_WITH_GENERICS"); - } - } - } - - private bool is_instance_of_generic_parameter(type_node tn) - { - if (tn.is_generic_parameter) - return true; - else if (tn.is_generic_type_instance) - { - foreach (type_node inst_tn in tn.instance_params) - if (is_instance_of_generic_parameter(inst_tn)) - return true; - } - return false; - } - - public override void visit(SyntaxTree.procedure_attribute _procedure_attribute) - { - throw new NotSupportedError(get_location(_procedure_attribute)); - } - - public override void visit(SyntaxTree.label_definitions _label_definitions) - { - /*if (context.converting_block() == block_type.type_block && - context.converted_type.IsInterface) - { - throw new InvalidInterfaceMember(get_location(_label_definitions)); - }*/ - foreach (SyntaxTree.ident id in _label_definitions.labels.idents) - { - context.add_label_declaration(id.name, get_location(id)); - } - } - - private bool depended_from_generic_parameter(type_node tn) - { - //Ivan 1.09.08 added - if (tn == null) - return false; - if (tn.is_generic_parameter) - return true; - if (tn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.set_type) - { - return depended_from_generic_parameter(tn.element_type); - } - if (tn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.array_kind) - { - return depended_from_generic_parameter(tn.element_type); - } - ref_type_node rtn = tn as ref_type_node; - if (rtn != null) - { - return depended_from_generic_parameter(rtn.pointed_type); - } - generic_instance_type_node gitn = tn as generic_instance_type_node; - if (gitn == null) - return false; - foreach (type_node param in gitn.generic_parameters) - { - if (depended_from_generic_parameter(param)) - return true; - } - return false; - } - - private bool is_unsized_array(SyntaxTree.indexers_types indexes, out int rank) - { - rank = 1; - if (indexes == null) - return true; - bool wait_empty = false; - for (int i=0; i 32) - AddError(get_location(_array_type.indexers), "ARRAY_RANK_CANNOT_BE_GREATER_32"); - type_node ret = null; - type_node et = convert_strong(_array_type.elements_type); - //if (et == SystemLibrary.SystemLibrary.void_type) - //AddError(new VoidNotValid(get_location(_array_type.elemets_types))); - check_for_type_allowed(et,get_location(_array_type.elements_type)); - check_using_static_class(et, get_location(_array_type.elements_type)); - ret = convertion_data_and_alghoritms.type_constructor.create_unsized_array(et, - context.converted_namespace, rank, get_location(_array_type)); - return_value(ret); - return; - } - type_node_list ind_types = new type_node_list(); - foreach (SyntaxTree.type_definition td in _array_type.indexers.indexers) - { - type_node tn = convert_strong(td); - internal_interface ii = tn.get_internal_interface(internal_interface_kind.ordinal_interface); - if (ii == null) - { - AddError(new OrdinalTypeExpected(get_location(td))); - } - if (tn.IsEnum && tn is common_type_node) - { - common_type_node enum_ctn = tn as common_type_node; - int c = 0; - for (int i = 0; i < enum_ctn.const_defs.Count; i++) - { - class_constant_definition ccdn = enum_ctn.const_defs[i]; - if (ccdn.constant_value != null) - { - int nextc = Convert.ToInt32(ccdn.constant_value.value); - if (nextc - c != 1 && i != 0) - AddError(get_location(td), "ENUM_MUST_HAVE_SEQUENCED_VALUES"); - else if (nextc != 0 && i == 0) - AddError(get_location(td), "ENUM_MUST_HAVE_SEQUENCED_VALUES"); - c = nextc; - } - } - } - if (tn.type_special_kind == SemanticTree.type_special_kind.diap_type) - { - if (tn.base_type == SystemLibrary.SystemLibrary.uint_type || tn.base_type == SystemLibrary.SystemLibrary.int64_type || - tn.base_type == SystemLibrary.SystemLibrary.uint64_type) - //ordinal_type_interface oti = tn.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; - AddError(get_location(td), "RANGE_TOO_LARGE"); - if (tn.base_type == SystemLibrary.SystemLibrary.integer_type) - { - Int64 low = ((tn as SemanticTree.ICommonTypeNode).lower_value as int_const_node).constant_value; - Int64 high = ((tn as SemanticTree.ICommonTypeNode).upper_value as int_const_node).constant_value; - if (high-low >= int.MaxValue) - AddError(get_location(td), "RANGE_TOO_LARGE"); - } - } - else if (tn == SystemLibrary.SystemLibrary.uint_type || tn == SystemLibrary.SystemLibrary.int64_type || - tn == SystemLibrary.SystemLibrary.uint64_type || tn == SystemLibrary.SystemLibrary.integer_type) - AddError(get_location(td), "RANGE_TOO_LARGE"); - ind_types.AddElement(tn); - } - type_node elem_type = convert_strong(_array_type.elements_type); - //TODO: Сделать и массивы, связанные с generics! - if (depended_from_generic_parameter(elem_type)) - { - throw new NotSupportedError(get_location(_array_type.elements_type)); - } - check_for_type_allowed(elem_type,get_location(_array_type.elements_type)); - check_using_static_class(elem_type, get_location(_array_type.elements_type)); - for (int i = ind_types.Count - 1; i >= 0; i--) - { - internal_interface ii = ind_types[i].get_internal_interface(internal_interface_kind.ordinal_interface); - ordinal_type_interface oti_ind = (ordinal_type_interface)ii; - elem_type = convertion_data_and_alghoritms.type_constructor.get_array_type(oti_ind, elem_type, - context.converted_namespace, get_location(_array_type)); - } - return_value(elem_type); - } - - public override void visit(SyntaxTree.indexers_types _indexers_types) - { - throw new NotSupportedError(get_location(_indexers_types)); - } - - private constant_node convert_strong_to_constant_node(SyntaxTree.expression expr) - { - expression_node exp = convert_strong(expr); - var is_const_section = (expr.Parent != null && (expr.Parent is const_definition)); - - var is_userdefined = false; - var cnf = exp as common_namespace_function_call; - if (cnf != null) - { - is_userdefined = ! (cnf.function_node.namespace_node.namespace_name.Equals("PABCSystem") || cnf.function_node.namespace_node.namespace_name.Equals("PABCSystem_implementation______")); - } - return convert_strong_to_constant_node(exp, exp.type, is_const_section && is_userdefined, is_const_section); - } - - public expression_node convert_strong_to_constant_or_function_call_for_varinit(expression_node exp) - { - return convert_strong_to_constant_or_function_call_for_varinit(exp, exp.type); - } - - private expression_node convert_strong_to_constant_or_function_call_for_varinit(expression_node exp, type_node tn) - { - if (exp is constant_node) - { - possible_type_convertions pct = type_table.get_convertions(exp.type, tn); - if (pct.first != null && pct.first.convertion_method.IsOperator) - //if (convertion_data_and_alghoritms.can_convert_type(exp, tn)) - return convertion_data_and_alghoritms.convert_type(exp, tn); - else return convert_strong_to_constant_node(exp, tn); - } - if (exp is array_initializer) - { - //if (tn.type_special_kind != SemanticTree.type_special_kind.array_wrapper) - { - //exp.type = DeduceType(exp.type,exp.location); - exp = ConvertArrayInitializer(tn, exp as array_initializer); - return exp; - //return convertion_data_and_alghoritms.convert_type(exp,tn); - } -// else -// { -// exp.type = tn; -// return exp; -// } - } - else if (exp is compiled_static_method_call && (exp.type.type_special_kind == SemanticTree.type_special_kind.set_type || exp.type.type_special_kind == SemanticTree.type_special_kind.base_set_type)) - { - if (!(tn == exp.type) && !type_table.is_derived(tn, exp.type) && !(convertion_data_and_alghoritms.can_convert_type(exp, tn))) - { - AddError(new CanNotConvertTypes(exp, exp.type, tn, exp.location)); - } - if (tn.element_type != null) - { - ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; - if (oti != null) - { - compiled_static_method_call cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as compiled_function_node, null); - cmc.parameters.AddElement(exp); - cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); - cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); - cmc.ret_type = tn; - return new compiled_static_method_call_as_constant(cmc, null); - } - else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) - { - compiled_static_method_call cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as compiled_function_node, null); - cmc.parameters.AddElement(exp); - cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length, null)); - cmc.ret_type = tn; - return new compiled_static_method_call_as_constant(cmc, null); - } - } - return new compiled_static_method_call_as_constant(exp as compiled_static_method_call, null); - } - else if (exp is common_namespace_function_call && (exp.type.type_special_kind == SemanticTree.type_special_kind.set_type || exp.type.type_special_kind == SemanticTree.type_special_kind.base_set_type)) - { - if (!(tn == exp.type) && !type_table.is_derived(tn, exp.type) && !(convertion_data_and_alghoritms.can_convert_type(exp, tn))) - { - AddError(new CanNotConvertTypes(exp, exp.type, tn, exp.location)); - } - if (tn.element_type != null) - { - ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; - if (oti != null) - { - common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node, null); - cmc.parameters.AddElement(exp); - cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); - cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); - cmc.ret_type = tn; - return new common_namespace_function_call_as_constant(cmc, null); - } - else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) - { - common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node, null); - cmc.parameters.AddElement(exp); - cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length, null)); - cmc.ret_type = tn; - return new common_namespace_function_call_as_constant(cmc, null); - } - } - return new common_namespace_function_call_as_constant(exp as common_namespace_function_call, null); - } - else if (exp is record_initializer) - { - if (tn is common_type_node) - exp = ConvertRecordInitializer(tn as common_type_node, exp as record_initializer); - else if (tn is compiled_type_node) - throw new NotSupportedError(exp.location); - return exp; - } - switch (SemanticRules.VariableInitializationParams) - { - case VariableInitializationParams.ConstructorCall: - if ((exp is common_constructor_call) || (exp is compiled_constructor_call)) - return convertion_data_and_alghoritms.convert_type(exp, tn); - break; - case VariableInitializationParams.Expression: - if (exp.type != null) - return convertion_data_and_alghoritms.convert_type(exp, tn); - break; - } - return convert_strong_to_constant_node(exp, tn); - } - - private constant_node convert_strong_to_constant_node(SyntaxTree.expression expr, type_node tn) - { - var exp = convert_strong(expr); - var is_const_section = (expr.Parent != null && (expr.Parent is const_definition)); - - var is_userdefined = false; - var cnf = exp as common_namespace_function_call; - if (cnf != null) - { - is_userdefined = !(cnf.function_node.namespace_node.namespace_name.Equals("PABCSystem") || cnf.function_node.namespace_node.namespace_name.Equals("PABCSystem_implementation______")); - } - - return convert_strong_to_constant_node(exp, tn, is_const_section && is_userdefined, is_const_section); - } - - private void check_set_for_constant(common_namespace_function_call cnfc) - { - expressions_list exprs = null; - if (cnfc.function_node == SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node) - exprs = get_set_initializer(cnfc); - else exprs = cnfc.parameters; - foreach (expression_node en in exprs) - if (en is common_namespace_function_call) - { - cnfc = en as common_namespace_function_call; - if (cnfc.function_node == PascalABCCompiler.SystemLibrary.SystemLibInitializer.SetUnionProcedure.sym_info as common_namespace_function_node - || cnfc.function_node == PascalABCCompiler.SystemLibrary.SystemLibInitializer.SetSubtractProcedure.sym_info as common_namespace_function_node - || cnfc.function_node == PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node - || cnfc.function_node == PascalABCCompiler.SystemLibrary.SystemLibInitializer.SetIntersectProcedure.sym_info as common_namespace_function_node - || cnfc.function_node == PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateDiapason.sym_info as common_namespace_function_node - || cnfc.function_node == PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateObjDiapason.sym_info as common_namespace_function_node) - check_set_for_constant(en as common_namespace_function_call); - else AddError(en.location, "CONSTANT_EXPRESSION_EXPECTED"); - } - else - if (!(en is constant_node /*|| en is statements_expression_node*/)) AddError(en.location, "CONSTANT_EXPRESSION_EXPECTED"); - } - - private constant_node convert_strong_to_constant_node(expression_node expr, type_node tn, bool is_const_section_and_userfuncall = false, bool is_const_section = false, location parent_loc = null) - { - location loc = expr.location; - if (parent_loc != null) - loc = parent_loc; - constant_node constant = null; - try_convert_typed_expression_to_function_call(ref expr); - if (expr is null_const_node) - { - if (!(tn is null_type_node) && !type_table.is_with_nil_allowed(tn)) - AddError(loc, "NIL_WITH_VALUE_TYPES_NOT_ALLOWED"); - return null_const_node.get_const_node_with_type(tn, expr as null_const_node); - } - if (expr is compiled_static_method_call) - { - compiled_static_method_call csmc = expr as compiled_static_method_call; - - if (csmc.type != null && csmc.type != SystemLibrary.SystemLibrary.void_type && (csmc.function_node.IsSpecialName && csmc.function_node.is_readonly || NetHelper.NetHelper.PABCSystemType != null && csmc.function_node.cont_type.compiled_type.Assembly == NetHelper.NetHelper.PABCSystemType.Assembly || !is_const_section)) - constant = new compiled_static_method_call_as_constant(csmc, expr.location); - } - else if (expr is common_namespace_function_call && SystemLibrary.SystemLibInitializer.CreateSetProcedure != null && (expr as common_namespace_function_call).function_node == SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node) - { - common_namespace_function_call cnfc = expr as common_namespace_function_call; - expressions_list exprs = get_set_initializer(cnfc); - check_set_for_constant(cnfc); - foreach (expression_node en in exprs) - { - if (en is common_namespace_function_call) - { - common_namespace_function_call cnfc2 = en as common_namespace_function_call; - check_set_for_constant(cnfc2); - } - else - if (!(en is constant_node)) AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); - } - constant = new common_namespace_function_call_as_constant(cnfc, loc); - } - else if (is_const_section_and_userfuncall && (expr is basic_function_call || expr is common_namespace_function_call)) // только в разделе const - { - AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); - } - else if (expr is common_namespace_function_call) - { - common_namespace_function_call cnfc=expr as common_namespace_function_call; - foreach (expression_node el in cnfc.parameters) - convert_strong_to_constant_node(el, el.type, false, false, cnfc.location); - //if (cnfc.function_node.namespace_node == context.converted_namespace) - // AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); - // throw new ConstantExpressionExpected(loc); - constant = new common_namespace_function_call_as_constant(expr as common_namespace_function_call, loc); - } - else if (expr is basic_function_call) - { - basic_function_call cnfc=expr as basic_function_call; - //if (cnfc.function_node.namespace_node == context.converted_namespace) - // throw new ConstantExpressionExpected(loc); - foreach (expression_node el in cnfc.parameters) - convert_strong_to_constant_node(el, el.type); - constant = new basic_function_call_as_constant(expr as basic_function_call, loc); - } - else if (expr is typed_expression) - { - expr = convertion_data_and_alghoritms.convert_type(expr, tn); - if (expr is common_constructor_call) - { - constant = new common_constructor_call_as_constant(expr as common_constructor_call, null); - } - else - if (expr is typed_expression) - { - if (const_def_type != null) - { - expr = convertion_data_and_alghoritms.convert_type(expr, const_def_type); - tn = const_def_type; - constant = new common_constructor_call_as_constant(expr as common_constructor_call, null); - } - else - { - base_function_call bfc = ((expr as typed_expression).type as delegated_methods).proper_methods[0]; - common_type_node del = - convertion_data_and_alghoritms.type_constructor.create_delegate(context.get_delegate_type_name(), bfc.simple_function_node.return_value_type, bfc.simple_function_node.parameters, context.converted_namespace, null); - context.converted_namespace.types.AddElement(del); - tn = del; - expr = convertion_data_and_alghoritms.explicit_convert_type(expr, del); - expr.type = tn; - constant = new common_constructor_call_as_constant(expr as common_constructor_call, loc); - } - } - } - - else if (expr is namespace_constant_reference) - { - constant = (expr as namespace_constant_reference).constant.const_value; - convertion_data_and_alghoritms.check_convert_type(constant,tn,expr.location); - if ((tn.type_special_kind == SemanticTree.type_special_kind.set_type || tn.type_special_kind == SemanticTree.type_special_kind.base_set_type) && tn.element_type != null) - { - ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; - if (oti != null) - { - common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node,null); - cmc.parameters.AddElement(expr); - cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); - cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); - cmc.ret_type = tn; - constant = new common_namespace_function_call_as_constant(cmc,null); - } - else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) - { - common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node,null); - cmc.parameters.AddElement(expr); - cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length,null)); - cmc.ret_type = tn; - constant = new common_namespace_function_call_as_constant(cmc,null); - } - } - else - if (tn.type_special_kind == SemanticTree.type_special_kind.short_string) - { - /*common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node,null); - cmc.parameters.AddElement(expr); - cmc.parameters.AddElement(new int_const_node((tn as short_string_type_node).Length,null));*/ - expression_node cmc = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(expr,SystemLibrary.SystemLibrary.string_type),new int_const_node((tn as short_string_type_node).Length,null)); - constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call,null); - } - /*expression_node e = convertion_data_and_alghoritms.convert_type(constant.get_constant_copy(expr.location), tn); - switch (e.semantic_node_type) - { - case semantic_node_type.compiled_constructor_call: - constant = new compiled_constructor_call_as_constant(e as compiled_constructor_call, loc); - break; - default: - constant = e as constant_node; - break; - }*/ - /*if (constant.get_object_value() != null) - { - //if (const_def_type != null) - { - expression_node e = convertion_data_and_alghoritms.convert_type(constant.get_constant_copy(expr.location), tn); - switch (e.semantic_node_type) - { - case semantic_node_type.compiled_constructor_call: - constant = new compiled_constructor_call_as_constant(e as compiled_constructor_call, loc); - break; - default: - constant = e as constant_node; - break; - } - } - } - else - { - //if (const_def_type != null) - { - expression_node e = convertion_data_and_alghoritms.convert_type(expr, tn); - switch (e.semantic_node_type) - { - case semantic_node_type.compiled_constructor_call: - constant = new compiled_constructor_call_as_constant(e as compiled_constructor_call, loc); - break; - default: - constant = e as constant_node; - break; - } - } - }*/ - return constant; - } - else if (expr is function_constant_reference) - { - constant = (expr as function_constant_reference).constant.const_value; - convertion_data_and_alghoritms.check_convert_type(constant,tn,expr.location); - if ((tn.type_special_kind == SemanticTree.type_special_kind.set_type || tn.type_special_kind == SemanticTree.type_special_kind.base_set_type) && tn.element_type != null) - { - ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; - if (oti != null) - { - common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node,null); - cmc.parameters.AddElement(expr); - cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); - cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); - cmc.ret_type = tn; - constant = new common_namespace_function_call_as_constant(cmc,null); - } - else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) - { - common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node,null); - cmc.parameters.AddElement(expr); - cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length,null)); - cmc.ret_type = tn; - constant = new common_namespace_function_call_as_constant(cmc,null); - } - } - else - if (tn.type_special_kind == SemanticTree.type_special_kind.short_string) - { - /*common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node,null); - cmc.parameters.AddElement(expr); - cmc.parameters.AddElement(new int_const_node((tn as short_string_type_node).Length,null));*/ - expression_node cmc = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(expr,SystemLibrary.SystemLibrary.string_type),new int_const_node((tn as short_string_type_node).Length,null)); - constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call,null); - } - return constant; - } - else if (expr is static_compiled_variable_reference && !(expr as static_compiled_variable_reference).var.IsLiteral) - { - constant = new compiled_static_field_reference_as_constant(expr as static_compiled_variable_reference, null); - return constant; - } - else if (expr is default_operator_node) - constant = new default_operator_node_as_constant(expr as default_operator_node, null); - else - { - constant = expr as constant_node; - if (tn.type_special_kind == SemanticTree.type_special_kind.short_string) - { - /*common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node,null); - cmc.parameters.AddElement(expr); - cmc.parameters.AddElement(new int_const_node((tn as short_string_type_node).Length,null));*/ - expression_node cmc = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node, null, convertion_data_and_alghoritms.convert_type(expr, SystemLibrary.SystemLibrary.string_type), new int_const_node((tn as short_string_type_node).Length, null)); - if (cmc is common_namespace_function_call) - constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call, null); - else - constant = new compiled_static_method_call_as_constant(cmc as compiled_static_method_call, null); - } - //else - //constant = convertion_data_and_alghoritms.convert_type(constant, tn) as constant_node; - if (expr is static_compiled_variable_reference) - { - compiled_class_constant_definition cccd = NetHelper.NetHelper.ConvertToConstant(((static_compiled_variable_reference)expr).var); - if (cccd != null) - constant = cccd.const_value; - else - constant = new compiled_static_field_reference_as_constant(expr as static_compiled_variable_reference, null); - } - - } - - if (constant == null) - AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); - if (IsBoundedArray(tn) || IsUnsizedArray(tn)) - { - if (!(constant is array_const)) - AddError(loc, "ARRAY_CONST_EXPECTED"); - constant = ConvertArrayConst(tn, constant as array_const); - } - else - if (tn is common_type_node) - { - if (tn.type_special_kind != SemanticTree.type_special_kind.set_type && tn.type_special_kind != SemanticTree.type_special_kind.base_set_type && tn.type_special_kind != SemanticTree.type_special_kind.diap_type) - { - if (!tn.is_value) - { - if (expr is common_constructor_call) - return constant; - if (expr is common_constructor_call_as_constant) - return expr as common_constructor_call_as_constant; - convertion_data_and_alghoritms.check_convert_type(expr,tn,expr.location); - return constant; - //AddError(new CanNotConvertTypes(expr,expr.type,tn,expr.location)); - //throw new NotSupportedError(loc); - } - if ((tn as common_type_node).IsEnum) - { - convertion_data_and_alghoritms.check_convert_type(expr,tn,expr.location); - enum_const_node ecn = expr as enum_const_node; - if (ecn == null) AddError(expr.location, "CONSTANT_EXPRESSION_EXPECTED"); - return ecn; - } - if (!(constant is record_constant)) - AddError(loc, "RECORD_CONST_EXPECTED"); - constant = ConvertRecordConst(tn as common_type_node, constant as record_constant); - } - else if (tn.type_special_kind == SemanticTree.type_special_kind.diap_type) - { - constant = expr as constant_node; - if (constant == null) - AddError(expr.location, "CONSTANT_EXPRESSION_EXPECTED"); - //constant = (expr as namespace_constant_reference).constant.const_value; - convertion_data_and_alghoritms.check_convert_type(constant,tn,expr.location); - ordinal_type_interface oti = tn.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; - bool success = false; - int val = convertion_data_and_alghoritms.convert_type_to_int_constant(constant, out success); - if (success) - { - int left = convertion_data_and_alghoritms.convert_type_to_int_constant(oti.lower_value, out success); - if (success) - { - int right = convertion_data_and_alghoritms.convert_type_to_int_constant(oti.upper_value, out success); - if (success) - if (val < left || val > right) - AddError(loc, "OUT_OF_RANGE"); - } - } - } - else - { - //obrezka konstantnogo mnozhestva - if (!(tn == expr.type) && !type_table.is_derived(tn,expr.type)) - { - AddError(new CanNotConvertTypes(expr,expr.type,tn,expr.location)); - } - if (tn.element_type != null) - { - ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; - if (oti != null) - { - base_function_call cmc = null; - if (SystemLibrary.SystemLibInitializer.ClipFunction.sym_info is common_namespace_function_node) - cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node, null); - else - cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as compiled_function_node, null); - cmc.parameters.AddElement(expr); - cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); - cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); - cmc.ret_type = tn; - if (cmc is common_namespace_function_call) - constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call, null); - else - constant = new compiled_static_method_call_as_constant(cmc as compiled_static_method_call, null); - } - else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) - { - base_function_call cmc = null; - if (SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info is common_namespace_function_node) - cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node, null); - else - cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as compiled_function_node, null); - cmc.parameters.AddElement(expr); - cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length,null)); - cmc.ret_type = tn; - if (cmc is common_namespace_function_call) - constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call, null); - else - constant = new compiled_static_method_call_as_constant(cmc as compiled_static_method_call, null); - } - } - } - } - else - { - expression_node exprc = convertion_data_and_alghoritms.convert_type(constant, tn); - switch (exprc.semantic_node_type) - { - case semantic_node_type.compiled_constructor_call: - constant = new compiled_constructor_call_as_constant(exprc as compiled_constructor_call, loc); - break; - case semantic_node_type.compiled_static_method_call: - constant = new compiled_static_method_call_as_constant(exprc as compiled_static_method_call, loc); - break; - case semantic_node_type.basic_function_call: - constant = new basic_function_call_as_constant(exprc as basic_function_call, loc); - break; - case semantic_node_type.common_namespace_function_call: - constant = new common_namespace_function_call_as_constant(exprc as common_namespace_function_call, loc); - break; - default: - constant = exprc as constant_node; - break; - } - } - return constant; - } - - internal common_type_node CreateDelegate(function_node fn) - { - common_type_node del = - convertion_data_and_alghoritms.type_constructor.create_delegate(context.get_delegate_type_name(), fn.return_value_type, fn.parameters, context.converted_namespace, null); - context.converted_namespace.types.AddElement(del); - return del; - } - - internal expression_node CreateDelegateCall(base_function_call fn_call) - { - common_type_node del = CreateDelegate(fn_call.simple_function_node); - common_constructor_call deleg_costructor_call = new common_constructor_call(del.methods[0], fn_call.location); - deleg_costructor_call.parameters.AddElement((base_function_call)fn_call); - return deleg_costructor_call; - } - - private record_initializer ConvertRecordInitializer(common_type_node ctn, record_initializer constant) - { - location loc = constant.location; - if (!ctn.is_value_type) - AddError(loc, "RECORD_CONST_NOT_ALLOWED_{0}", ctn.name); - if (ctn.fields.Count != constant.record_const_definition_list.Count) - AddError(loc, "INVALID_RECORD_CONST_FIELD_COUNT"); - constant.type = ctn; - constant.field_values.Clear(); - for (int i = 0; i < ctn.fields.Count; i++) - { - class_field cf = ctn.fields[i]; - if (cf.name.ToLower() != constant.record_const_definition_list[i].name.name.ToLower()) - AddError(get_location(constant.record_const_definition_list[i].name), "FIELD_NAME_SHOULD_BE_EQUAL_RECORD_FIELD_NAME", cf.name); - expression_node en = convert_strong_to_constant_or_function_call_for_varinit(convert_strong(constant.record_const_definition_list[i].val),cf.type); - en.type = cf.type; - constant.field_values.Add(en); - } - return constant; - } - - private array_initializer ConvertNDimArrayInitializer(type_node tn, int cur_rank, type_node element_type, array_initializer constant) - { - array_internal_interface aii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface; - int rank = aii.rank; - int size = -1; - for (int i=0; i= rank) - constant.element_values[i] = ConvertArrayInitializer(tn.element_type, e as array_initializer); - //AddError(new CanNotConvertTypes(e,e.type,tn.element_type,e.location)); - else - constant.element_values[i] = ConvertNDimArrayInitializer(tn,cur_rank + 1, element_type, e as array_initializer); - } - else if (e is record_initializer) - { - if (element_type is common_type_node) - constant.element_values[i] = ConvertRecordInitializer(element_type as common_type_node, e as record_initializer); - else throw new NotSupportedError(constant.element_values[i].location); - } - else - { - if (cur_rank != rank) - AddError(constant.location, "RANK_MISMATCH_IN_INITILIALIZER"); - constant.element_values[i] = convertion_data_and_alghoritms.convert_type(constant.element_values[i], element_type); - } - } - constant.type = tn; - return constant; - } - - private expression_node ConvertArrayInitializer(type_node tn, array_initializer constant) - { - type_node element_type = null; - if (IsBoundedArray(tn)) - { - bounded_array_interface bai = tn.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface; - element_type = bai.element_type; - ordinal_type_interface oti_indexer = bai.ordinal_type_interface; - int arr_length = oti_indexer.ordinal_type_to_int(oti_indexer.upper_value) - oti_indexer.ordinal_type_to_int(oti_indexer.lower_value) + 1; - if (arr_length != constant.element_values.Count) - AddError(constant.location, "ARRAY_CONST_{0}_ELEMENTS_EXPECTED", arr_length); - } - else - if (IsUnsizedArray(tn)) - { - array_internal_interface aii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface; - element_type = aii.element_type; - if (aii.rank > 1) - { - array_initializer cnst = ConvertNDimArrayInitializer(tn,1,element_type,constant); - cnst.type = tn; - return cnst; - } - } - else if (tn == SystemLibrary.SystemLibrary.complex_type && constant.element_values.Count == 2) - { - compiled_constructor_call cccall = new compiled_constructor_call(SystemLibrary.SystemLibrary.complex_type_constructor, null); - cccall.parameters.AddElement(convertion_data_and_alghoritms.convert_type(constant.element_values[0], SystemLibrary.SystemLibrary.double_type)); - cccall.parameters.AddElement(convertion_data_and_alghoritms.convert_type(constant.element_values[1], SystemLibrary.SystemLibrary.double_type)); - compiled_constructor_call_as_constant cccall_cnst = new compiled_constructor_call_as_constant(cccall, null); - return cccall_cnst; - } - else - AddError(new CanNotConvertTypes(constant,constant.type,tn,constant.location));//CompilerInternalError("Unexpected array type"); - for (int i = 0; i < constant.element_values.Count; i++) - if (constant.element_values[i] is array_initializer) - constant.element_values[i] = ConvertArrayInitializer(element_type, constant.element_values[i] as array_initializer); - else if (constant.element_values[i] is record_initializer) - { - if (element_type is common_type_node) - constant.element_values[i] = ConvertRecordInitializer(element_type as common_type_node, constant.element_values[i] as record_initializer); - else throw new NotSupportedError(constant.element_values[i].location); - } - else - { - constant.element_values[i] = convertion_data_and_alghoritms.convert_type(constant.element_values[i], element_type); - } - constant.type = tn; - return constant; - } - - private array_const ConvertNDimArrayConst(type_node tn, int cur_rank, type_node element_type, array_const constant) - { - array_internal_interface aii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface; - int rank = aii.rank; - int size = -1; - for (int i=0; i=rank) - constant.element_values[i] = ConvertArrayConst(tn.element_type,e as array_const); - //AddError(new CanNotConvertTypes(e,e.type,tn.element_type,e.location)); - else - constant.element_values[i] = ConvertNDimArrayConst(tn,cur_rank+1,element_type,e as array_const); - } - else if (e is record_constant) - { - if (element_type is common_type_node) - constant.element_values[i] = ConvertRecordConst(element_type as common_type_node, e as record_constant); - else AddError(new NotSupportedError(constant.element_values[i].location)); - } - else - { - if (cur_rank != rank) - AddError(constant.location, "RANK_MISMATCH_IN_INITILIALIZER"); - constant.element_values[i] = convert_strong_to_constant_node(constant.element_values[i], element_type); - } - } - constant.SetType(tn); - return constant; - } - - private array_const ConvertArrayConst(type_node tn, array_const constant) - { - type_node element_type = null; - if (IsBoundedArray(tn)) - { - bounded_array_interface bai = tn.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface; - element_type = bai.element_type; - ordinal_type_interface oti_indexer = bai.ordinal_type_interface; - int arr_length = oti_indexer.ordinal_type_to_int(oti_indexer.upper_value) - oti_indexer.ordinal_type_to_int(oti_indexer.lower_value) + 1; - if (arr_length != constant.element_values.Count) - AddError(constant.location, "ARRAY_CONST_{0}_ELEMENTS_EXPECTED", arr_length); - } - else - if (IsUnsizedArray(tn)) - { - array_internal_interface aii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface; - element_type = aii.element_type; - if (aii.rank > 1) - { - array_const cnst = ConvertNDimArrayConst(tn,1,element_type,constant); - cnst.SetType(tn); - return cnst; - } - } - else - throw new CompilerInternalError("Unexpected array type"); - for (int i = 0; i < constant.element_values.Count; i++) - constant.element_values[i] = convert_strong_to_constant_node(constant.element_values[i], element_type); - constant.SetType(tn); - return constant; - } - - private record_constant ConvertRecordConst(common_type_node ctn, record_constant constant) - { - location loc = constant.location; - if (!ctn.is_value_type) - AddError(loc, "RECORD_CONST_NOT_ALLOWED_{0}", ctn.name); - if (ctn.fields.Count != constant.record_const_definition_list.Count) - AddError(loc, "INVALID_RECORD_CONST_FIELD_COUNT"); - constant.SetType(ctn); - constant.field_values.Clear(); - bool tmp = this.is_typed_const_def; - this.is_typed_const_def = true; - for (int i = 0; i < ctn.fields.Count; i++) - { - class_field cf = ctn.fields[i]; - if (cf.name.ToLower() != constant.record_const_definition_list[i].name.name.ToLower()) - AddError(get_location(constant.record_const_definition_list[i].name), "FIELD_NAME_SHOULD_BE_EQUAL_RECORD_FIELD_NAME", cf.name); - constant.field_values.Add(convert_strong_to_constant_node(constant.record_const_definition_list[i].val, cf.type)); - } - this.is_typed_const_def = tmp; - return constant; - } - - public override void visit(SyntaxTree.diapason _diapason) - { - constant_node cnleft = convert_strong_to_constant_node(_diapason.left); - constant_node cnright = convert_strong_to_constant_node(_diapason.right); - type_node tn = convertion_data_and_alghoritms.type_constructor.get_pascal_diap(cnleft, cnright, get_location(_diapason.left), - context.converted_namespace, get_location(_diapason.right)); - return_value(tn); - } - - public override void visit(SyntaxTree.ref_type _ref_type) - { - if (_ref_type.pointed_to is SyntaxTree.named_type_reference && - ((_ref_type.pointed_to as SyntaxTree.named_type_reference).names.Count == 1) && - context.CurrentScope.Find((_ref_type.pointed_to as SyntaxTree.named_type_reference).names[0].name) == null) - { - //это указатель на тип который еще не описан - if (!is_direct_type_decl) - AddError(new UndefinedNameReference((_ref_type.pointed_to as SyntaxTree.named_type_reference).names[0].name,get_location(_ref_type.pointed_to))); - return_value(GetWaitedRefType((_ref_type.pointed_to as SyntaxTree.named_type_reference).names[0].name, get_location(_ref_type.pointed_to))); - } - else - { - type_node tn = convert_strong(_ref_type.pointed_to); - if (tn.is_generic_parameter) - { - if (SemanticRules.AllowPointersForGenericParameters) - { - get_type_abilities(tn).useful_for_pointers = true; - } - else - { - AddError(get_location(_ref_type), "POINTERS_OF_GENERIC_PARAMETERS_NOT_ALLOWED"); - } - } - else - { - if (!tn.is_value /*&& tn.type_special_kind != SemanticTree.type_special_kind.array_kind && tn.type_special_kind != SemanticTree.type_special_kind.set_type && tn.type_special_kind != SemanticTree.type_special_kind.array_wrapper && tn.type_special_kind != SemanticTree.type_special_kind.binary_file - && tn.type_special_kind != SemanticTree.type_special_kind.binary_file*/ && !(tn is ref_type_node) && tn != SystemLibrary.SystemLibrary.pointer_type && tn.type_special_kind != SemanticTree.type_special_kind.short_string && tn.type_special_kind != SemanticTree.type_special_kind.diap_type && !tn.IsEnum && - !(tn.semantic_node_type == semantic_node_type.indefinite_type)) - AddError(get_location(_ref_type), "POINTERS_OF_REF_TYPES_NOT_ALLOWED"); - } - ref_type_node rtn = tn.ref_type; - if (rtn != null) - { - rtn.loc = get_location(_ref_type); - if (SemanticRules.StrongPointersTypeCheckForDotNet) - //CheckPointersTypeForDotNetFramework(tn, get_location(_ref_type.pointed_to)); - RefTypesForCheckPointersTypeForDotNetFramework.Add(rtn); - return_value(rtn); - } - else - { - return_value(SystemLibrary.SystemLibrary.pointer_type); - } - } - } - - internal bool CheckPointersTypeForDotNetFramework(type_node tn, location loc) - { - type_node ttn = FindBadTypeNodeForPointersInDotNetFramework(tn); - __findBadTypeNodeForPointersPreparedTypes.Clear(); - if (ttn != null) - { - AddErrorCheckPointersTypeForDotNetFramework(tn, ttn, loc); - return false; - } - return true; - } - - public void AddErrorCheckPointersTypeForDotNetFramework(type_node tn, type_node ttn, location loc) - { - if (tn == ttn) - AddError(loc, "CANNOT_DECLARED_POINTER_TO_REFERENCE_TYPE"); - else - AddError(loc, "CANNOT_DECLARED_POINTER_TO_RECORD_CONTAINS_REFERENCE_FIELDS"); - } - private List __findBadTypeNodeForPointersPreparedTypes = new List(); - private type_node FindBadTypeNodeForPointersInDotNetFramework(type_node tn) - { - if (__findBadTypeNodeForPointersPreparedTypes.Contains(tn)) - return null; - __findBadTypeNodeForPointersPreparedTypes.Add(tn); - if (tn.semantic_node_type == semantic_node_type.indefinite_type) - { - return null; - } - if (tn.is_generic_parameter) - { - if (SemanticRules.AllowPointersForGenericParameters) - { - get_type_abilities(tn).useful_for_pointers = true; - return null; - } - else - { - return tn; - } - } - type_node btn = null; - if (tn is ref_type_node) - return FindBadTypeNodeForPointersInDotNetFramework((tn as ref_type_node).pointed_type); - if (tn == SystemLibrary.SystemLibrary.pointer_type || tn == SystemLibrary.SystemLibrary.void_type) - return null; - if (tn.is_value) - { - generic_instance_type_node gitn = tn as generic_instance_type_node; - if (gitn != null) - { - List ftypes = gitn.all_field_types; - foreach (type_node ftype in ftypes) - { - if ((btn = FindBadTypeNodeForPointersInDotNetFramework(ftype)) != null) - return btn; - } - return null; - } - if (tn is common_type_node) - { - if (tn.IsEnum || tn.type_special_kind == SemanticTree.type_special_kind.diap_type) return null; - common_type_node ctn = tn as common_type_node; - foreach (class_field cf in ctn.fields) - if (!cf.IsStatic) - if ((btn = FindBadTypeNodeForPointersInDotNetFramework(cf.type)) != null) - return btn; - return null; - } - if (tn is compiled_type_node) - { - compiled_type_node ctn = tn as compiled_type_node; - if (ctn.IsPrimitive) - return null; - System.Reflection.FieldInfo[] fields = ctn.compiled_type.GetFields(); - foreach (System.Reflection.FieldInfo fi in fields) - if (!fi.IsStatic) - if ((btn = FindBadTypeNodeForPointersInDotNetFramework(compiled_type_node.get_type_node(fi.FieldType))) != null) - return btn; - return null; - } - } - /*if (IsBoudedArray(el_type)) - { - //это обычный массив - bounded_array_interface bai = (bounded_array_interface)el_type.get_internal_interface(internal_interface_kind.bounded_array_interface); - return CanUseThisTypeForTypedFiles(bai.element_type); - }*/ - if (tn == SystemLibrary.SystemLibrary.string_type || tn.type_special_kind == SemanticTree.type_special_kind.set_type || tn.type_special_kind == SemanticTree.type_special_kind.short_string || tn.type_special_kind == SemanticTree.type_special_kind.array_wrapper - || tn.type_special_kind == SemanticTree.type_special_kind.typed_file || tn.type_special_kind == SemanticTree.type_special_kind.binary_file || tn.type_special_kind == SemanticTree.type_special_kind.text_file - || tn.type_special_kind == SemanticTree.type_special_kind.array_kind) return null; - return tn; - } - - - /*private void ConvertStatement(SyntaxTree.statement stmt) - { - while (stmt != null) - { - if (stmt is SyntaxTree.if_node) - { - SyntaxTree.if_node _if_node = stmt as SyntaxTree.if_node; - - expression_node condition = convert_strong(_if_node.condition); - condition = convertion_data_and_alghoritms.convert_type(condition, SystemLibrary.SystemLibrary.bool_type); - - statements_list sl = new statements_list(get_location(_if_node.then_body)); - convertion_data_and_alghoritms.statement_list_stack_push(sl); - - context.enter_code_block_with_bind(); - statement_node then_st = convert_strong(_if_node.then_body); - context.leave_code_block(); - - sl = convertion_data_and_alghoritms.statement_list_stack.pop(); - if (sl.statements.Count > 0) - { - sl.statements.AddElement(then_st); - then_st = sl; - } - - if (_if_node.else_body != null) - { - sl = new statements_list(get_location(_if_node.else_body)); - convertion_data_and_alghoritms.statement_list_stack_push(sl); - } - - context.enter_code_block_with_bind(); - statement_node else_st = convert_weak(_if_node.else_body); - context.leave_code_block(); - - if (_if_node.else_body != null) - { - sl = convertion_data_and_alghoritms.statement_list_stack.pop(); - if (sl.statements.Count > 0) - { - sl.statements.AddElement(else_st); - else_st = sl; - } - } - - if_node if_node = new if_node(condition, then_st, else_st, get_location(_if_node)); - return_value(if_node); - return; - } - visit(stmt); - } - }*/ - - void CheckToEmbeddedStatementCannotBeADeclaration(SyntaxTree.statement st) - { - if (st != null && st is SyntaxTree.var_statement) - AddError(get_location(st), "EMBEDDED_SATATEMENT_CANNOT_BE_A_DECLARATION"); - } - - public override void visit(SyntaxTree.if_node _if_node) - { - expression_node condition = convert_strong(_if_node.condition); - condition = convertion_data_and_alghoritms.convert_type(condition, SystemLibrary.SystemLibrary.bool_type); - - // SSM 29/08/16 - /*var cc = condition as bool_const_node; - if (cc != null && cc.constant_value == false && _if_node.else_body == null) - { - // недостижимый код - ничего не генерировать - return_value(new empty_statement(get_location(_if_node))); - // перед этим надо обходить then_body - return; - }*/ - - CheckToEmbeddedStatementCannotBeADeclaration(_if_node.then_body); - CheckToEmbeddedStatementCannotBeADeclaration(_if_node.else_body); - - statements_list sl = new statements_list(get_location(_if_node.then_body)); - convertion_data_and_alghoritms.statement_list_stack_push(sl); - - context.enter_code_block_with_bind(); - statement_node then_st = convert_strong(_if_node.then_body); - context.leave_code_block(); - - sl = convertion_data_and_alghoritms.statement_list_stack.pop(); - if (sl.statements.Count > 0 || sl.local_variables.Count > 0) - { - sl.statements.AddElement(then_st); - then_st = sl; - } - - if (_if_node.else_body != null) - { - sl = new statements_list(get_location(_if_node.else_body)); - convertion_data_and_alghoritms.statement_list_stack_push(sl); - } - - context.enter_code_block_with_bind(); - statement_node else_st = convert_weak(_if_node.else_body); - context.leave_code_block(); - - if (_if_node.else_body != null) - { - sl = convertion_data_and_alghoritms.statement_list_stack.pop(); - if (sl.statements.Count > 0 || sl.local_variables.Count > 0) - { - sl.statements.AddElement(else_st); - else_st = sl; - } - } - - if_node if_node = new if_node(condition, then_st, else_st, get_location(_if_node)); - return_value(if_node); - } - - public override void visit(SyntaxTree.while_node _while_node) - { - expression_node expr = convert_strong(_while_node.expr); - expr = convertion_data_and_alghoritms.convert_type(expr, SystemLibrary.SystemLibrary.bool_type); - - CheckToEmbeddedStatementCannotBeADeclaration(_while_node.statements); - - while_node wn = new while_node(expr, get_location(_while_node)); - context.cycle_stack.push(wn); - - statements_list sl = new statements_list(get_location(_while_node.statements)); - convertion_data_and_alghoritms.statement_list_stack_push(sl); - - context.enter_code_block_with_bind(); - statement_node st = convert_strong(_while_node.statements); - context.leave_code_block(); - - sl = convertion_data_and_alghoritms.statement_list_stack.pop(); - if (sl.statements.Count > 0 || sl.local_variables.Count > 0) - { - sl.statements.AddElement(st); - st = sl; - } - - wn.body = st; - context.cycle_stack.pop(); - return_value(wn); - } - - public override void visit(SyntaxTree.repeat_node _repeat_node) - { - repeat_node rep = new repeat_node(get_location(_repeat_node)); - context.cycle_stack.push(rep); - - statements_list sl = new statements_list(get_location(_repeat_node.statements)); - convertion_data_and_alghoritms.statement_list_stack_push(sl); - - CheckToEmbeddedStatementCannotBeADeclaration(_repeat_node.statements); - - statement_node st = convert_strong(_repeat_node.statements); - - sl = convertion_data_and_alghoritms.statement_list_stack.pop(); - //if (!(st is statements_list)) - if (sl.statements.Count > 0 || sl.local_variables.Count > 0) - { - sl.statements.AddElement(st); - st = sl; - } - - rep.body = st; - expression_node expr = convert_strong(_repeat_node.expr); - expr = convertion_data_and_alghoritms.convert_type(expr, SystemLibrary.SystemLibrary.bool_type); - rep.condition = expr; - context.cycle_stack.pop(); - return_value(rep); - } - - - - - private expression_node additional_indexer_convertion(expression_node ind_expr, type_node array_type) - { - return convertion_data_and_alghoritms.convert_type(ind_expr, SystemLibrary.SystemLibrary.integer_type); - } - - private void indexer_as_expression_index(expression_node expr, SyntaxTree.expression_list parameters, - motivation mot, location loc) - { - try_convert_typed_expression_to_function_call(ref expr); - - // SSM 10.01.16 Tuple t[i] - var ent = expr.type as compiled_type_node; - - if (ent== null) - { - var eeee = expr.type as compiled_generic_instance_type_node; - if (eeee!= null) - ent = eeee.original_generic as compiled_type_node; - } - - if (ent != null) - { - var t = ent.compiled_type; - if (t != null && !t.IsArray && t.FullName.StartsWith("System.Tuple")) - { - expression eee = parameters.expressions[0]; - - if (parameters.expressions.Count > 1) - AddError(get_location(eee), "TUPLE_CAN_HAVE_ONLY_ONE_INDEX"); - - var cn = convert_strong_to_constant_node(eee); - - var v = cn as int_const_node; - - if (v != null) - { - if (v.constant_value<0 || v.constant_value >= t.GetGenericArguments().Count()) - AddError(cn.location, "TUPLE_INDEX_OUT_OF_RANGE_{0}", t.GetGenericArguments().Count()-1); - var dn = new dot_node(new semantic_addr_value(expr), new ident("Item" + (v.constant_value + 1).ToString(), eee.source_context),new SourceContext(loc.begin_line_num,loc.begin_column_num,loc.end_line_num,loc.end_column_num)); - visit(dn); - return; - } - else AddError(cn.location, "TUPLE_INDEX_MUST_BE_INTEGER_CONSTANT"); - } - } - // end SSM 09.01.16 Tuple t[i] - - if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_kind) - { - internal_interface ii = expr.type.get_internal_interface(internal_interface_kind.unsized_array_interface); - array_internal_interface aii = (array_internal_interface)ii; - int rank = aii.rank; - //TODO: Многомерные массивы. - expression_node ind_expr = convert_strong(parameters.expressions[0]); - ind_expr = additional_indexer_convertion(ind_expr, expr.type); - simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, aii.element_type, loc); - if (rank == 1) - for (int i = 1; i < parameters.expressions.Count; i++) - { - ii = sai.type.get_internal_interface(internal_interface_kind.unsized_array_interface); - location lloc = get_location(parameters.expressions[i]); - if (ii == null) - { - AddError(lloc, "{0}_DIMENSIONAL_ARRAY_CAN_NOT_HAVE_{1}_AND_MORE_INDEXING", i, i+1); - } - aii = (array_internal_interface)ii; - ind_expr = convert_strong(parameters.expressions[i]); - ind_expr = additional_indexer_convertion(ind_expr, sai.type); - sai = new simple_array_indexing(sai, ind_expr, aii.element_type, lloc); - } - else - { - if (rank != parameters.expressions.Count) - AddError(get_location(parameters), "{0}_DIMENSIONAL_ARRAY_CAN_NOT_HAVE_{1}_AND_MORE_INDEXING", rank, rank + 1); - List lst = new List(); - for (int i = 0; i < parameters.expressions.Count; i++) - { - location lloc = get_location(parameters.expressions[i]); - ind_expr = convert_strong(parameters.expressions[i]); - ind_expr = additional_indexer_convertion(ind_expr, sai.type); - lst.Add(ind_expr); - } - sai = new simple_array_indexing(expr, lst[0], aii.element_type, get_location(parameters)); - sai.expr_indices = lst.ToArray(); - } - switch (mot) - { - case motivation.address_receiving: - { - return_addressed_value(sai); - break; - } - case motivation.expression_evaluation: - { - return_value(sai); - break; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(sai); - break; - } - } - return; - } - else if (expr.type.type_special_kind == SemanticTree.type_special_kind.short_string) - { - if (parameters.expressions.Count != 1) - AddError(loc, "INVALID_PARAMETER_COUNT_IN_INDEXER"); - expression_node ind_expr = convert_strong(parameters.expressions[0]); - ind_expr = additional_indexer_convertion(ind_expr, expr.type); - //expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null)); - switch (mot) - { - case motivation.address_receiving: - { - simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, SystemLibrary.SystemLibrary.char_type, loc); - return_addressed_value(sai); - //return_addressed_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.SetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr) as common_namespace_function_call); - break; - } - case motivation.expression_evaluation: - { - return_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null))); - break; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null))); - break; - } - } - return; - - } - /*else if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper) - { - internal_interface ii = expr.type.get_internal_interface(internal_interface_kind.bounded_array_interface); - array_internal_interface aii = (array_internal_interface)ii; - //TODO: Многомерные массивы. - expression_node ind_expr = convert_strong(parameters.expressions[0]); - ind_expr = additional_indexer_convertion(ind_expr, expr.type); - simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, aii.element_type, loc); - for (int i = 1; i < parameters.expressions.Count; i++) - { - ii = sai.type.get_internal_interface(internal_interface_kind.bounded_array_interface); - location lloc = get_location(parameters.expressions[i]); - if (ii == null) - { - throw new NDimensionalArrayCanNotHaveNPlusOneIndexer(lloc, expr, i); - } - aii = (array_internal_interface)ii; - ind_expr = convert_strong(parameters.expressions[i]); - ind_expr = create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, ind_expr, - new int_const_node(ii.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),cmc.location)); - ind_expr = additional_indexer_convertion(ind_expr, sai.type); - sai = new simple_array_indexing(sai, ind_expr, aii.element_type, lloc); - } - switch (mot) - { - case motivation.address_reciving: - { - return_addressed_value(sai); - break; - } - case motivation.expression_evaluation: - { - return_value(sai); - break; - } - case motivation.semantic_node_reciving: - { - return_semantic_value(sai); - break; - } - } - return; - - if (factparams[i].semantic_node_type == semantic_node_type.common_method_call) - { - common_method_call cmc = (common_method_call)factparams[i]; - internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); - if (ii != null) - { - if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) - { - bounded_array_interface bai = (bounded_array_interface)ii; - class_field cf = bai.int_array; - expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); - expression_node right = cmc.parameters[0]; - //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); - right = convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); - right = create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, - new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),cmc.location)); - factparams[i] = new simple_array_indexing(left, right, cmc.type, cmc.location); - is_pascal_array_ref = true; - } - } - } - }*/ - if (expr.type.default_property_node == null) - { - if (expr.type.semantic_node_type != semantic_node_type.delegated_method) - { - AddError(loc, "NO_DEFAULT_PROPERTY_TO_TYPE_{0}", expr.type.PrintableName); - } - else - { - AddError(loc, "NO_DEFAULT_PROPERTY_TO_FUNCTION_TYPE"); - } - } - - if (expr.type.default_property_node.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - AddError(new CanNotReferenceToStaticPropertyWithExpression(expr.type.default_property_node, loc, expr.type)); - } - non_static_property_reference nspr = new non_static_property_reference(expr.type.default_property_node, expr, loc); - indexer_as_property_indexes(nspr, parameters, mot, loc); - //eto vrode rabotaet normalno. no imet v vidu - if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper) - { - expression_node en = ret.get_expression(); - if (en is non_static_property_reference) - { - non_static_property_reference cmc = (non_static_property_reference)en; - internal_interface ii = cmc.expression.type.get_internal_interface(internal_interface_kind.bounded_array_interface); - if (ii != null) - { - //if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) - { - bounded_array_interface bai = (bounded_array_interface)ii; - class_field cf = bai.int_array; - expression_node left = new class_field_reference(cf, cmc.expression, cmc.location); - expression_node right = cmc.fact_parametres[0]; - //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); - right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); - right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, - new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); - en = new simple_array_indexing(left, right, cmc.type, cmc.location); - //is_pascal_array_ref = true; - } - } - } - else - { - common_method_call cmc = (common_method_call)en; - internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); - if (ii != null) - { - //if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) - { - bounded_array_interface bai = (bounded_array_interface)ii; - class_field cf = bai.int_array; - expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); - expression_node right = cmc.parameters[0]; - //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); - right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); - right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, - new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); - en = new simple_array_indexing(left, right, cmc.type, cmc.location); - //is_pascal_array_ref = true; - } - } - } - return_value(en); - } - - return; - } - - private void indexer_as_type_indexes(type_node type, SyntaxTree.expression_list parameters, motivation mot, - location loc) - { - if (type.default_property_node == null) - { - if (type.semantic_node_type != semantic_node_type.delegated_method) - { - AddError(loc, "NO_DEFAULT_PROPERTY_TO_TYPE_{0}", type.PrintableName); - } - else - { - AddError(loc, "NO_DEFAULT_PROPERTY_TO_FUNCTION_TYPE"); - } - } - if (type.default_property_node.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - { - AddError(new CanNotReferenceToNonStaticPropertyWithType(type.default_property_node, loc, type)); - } - static_property_reference spr = new static_property_reference(type.default_property_node, loc); - indexer_as_property_indexes(spr, parameters, mot, loc); - return; - } - - private void indexer_as_property_indexes(static_property_reference spr, SyntaxTree.expression_list parameters, - motivation mot, location loc) - { - /*if (spr.property.parameters.Count==0) - { - switch(mot) - { - case motivation.expression_evaluation: - case motivation.semantic_node_reciving: - { - function_node fn=spr.property.get_function; - base_function_call_with_method bfc=convertion_data_and_alghoritms.create_simple_function_call(fn,loc,new expression_node[0]); - return_value(bfc); - return; - } - case motivation.address_reciving: - { - return_addressed_value(spr); - return; - } - } - throw new CompilerInternalError("Unsupported motivation"); - }*/ - if (spr.property.parameters.Count != 0) - { - if (parameters.expressions.Count != spr.property.parameters.Count) - { - AddError(loc, "PROPERTY_{0}_REFERENCE_WITH_INVALID_PARAMS_COUNT", spr.property.name); - } - for (int i = 0; i < parameters.expressions.Count; i++) - { - expression_node exp = convert_strong(parameters.expressions[i]); - exp = convertion_data_and_alghoritms.convert_type(exp, spr.property.parameters[i].type); - spr.fact_parametres.AddElement(exp); - } - } - switch (mot) - { - case motivation.expression_evaluation: - case motivation.semantic_node_reciving: - { - function_node fn = spr.property.get_function; - if (fn == null) - { - AddError(new ThisPropertyCanNotBeReaded(spr.property, loc)); - } - //expression_node bfc=convertion_data_and_alghoritms.create_simple_function_call(fn,loc,spr.fact_params.ToArray()); - base_function_call bfc = create_static_method_call(fn, loc, spr.property.comprehensive_type, false); - bfc.parameters.AddRange(spr.fact_parametres); - if (spr.property.parameters.Count != 0) - { - return_value(bfc); - return; - } - indexer_as_expression_index(bfc, parameters, mot, loc); - return; - } - case motivation.address_receiving: - { - if (spr.property.parameters.Count != 0) - { - return_addressed_value(spr); - return; - } - function_node fn = spr.property.get_function; - if (fn == null) - { - AddError(new ThisPropertyCanNotBeReaded(spr.property, loc)); - } - base_function_call bfc = create_static_method_call(fn, loc, spr.property.comprehensive_type, false); - bfc.parameters.AddRange(spr.fact_parametres); - indexer_as_expression_index(bfc, parameters, mot, loc); - return; - } - } - throw new CompilerInternalError("Unsupported motivation"); - } - - private void indexer_as_property_indexes(non_static_property_reference nspr, SyntaxTree.expression_list parameters, - motivation mot, location loc) - { - if (nspr.property.parameters.Count != 0) - { - if (parameters.expressions.Count != nspr.property.parameters.Count) - { - internal_interface ii = nspr.property.comprehensive_type.get_internal_interface(internal_interface_kind.bounded_array_interface); - if (ii != null) - { - //bounded_array_interface dii = (bounded_array_interface)ii; - - expression_node exp = convert_strong(parameters.expressions[0]); - exp = convertion_data_and_alghoritms.convert_type(exp, nspr.property.parameters[0].type); - nspr.fact_parametres.AddElement(exp); - - base_function_call bfc = null; - - for (int i = 1; i < parameters.expressions.Count; i++) - { - bfc = create_not_static_method_call(nspr.property.get_function, nspr.expression, exp.location, false); - bfc.parameters.AddRange(nspr.fact_parametres); - - location lloc = get_location(parameters.expressions[i]); - ii = bfc.type.get_internal_interface(internal_interface_kind.bounded_array_interface); - if (ii == null) - { - AddError(lloc, "{0}_DIMENSIONAL_ARRAY_CAN_NOT_HAVE_{1}_AND_MORE_INDEXING", i, i+1); - } - bounded_array_interface bii = (bounded_array_interface)ii; - exp = convert_strong(parameters.expressions[i]); - exp = convertion_data_and_alghoritms.convert_type(exp, bii.index_type); - nspr = new non_static_property_reference(bii.index_property, bfc, lloc); - nspr.fact_parametres.AddElement(exp); - } - } - else - { - AddError(loc, "PROPERTY_{0}_REFERENCE_WITH_INVALID_PARAMS_COUNT", nspr.property.name); - } - } - else - { - var lbvr = nspr.expression as local_block_variable_reference; - - //String 1 based - if (parameters.expressions.Count == 1 && - nspr.property.comprehensive_type == SystemLibrary.SystemLibrary.string_type && - !SemanticRules.NullBasedStrings && (lbvr == null || !lbvr.var.name.StartsWith("<>match"))) - { - nspr.fact_parametres.AddElement( - ConstructDecExpr( - convertion_data_and_alghoritms.convert_type( - convert_strong(parameters.expressions[0]), nspr.property.parameters[0].type), null)); - } - else - for (int i = 0; i < parameters.expressions.Count; i++) - { - expression_node exp = convert_strong(parameters.expressions[i]); - exp = convertion_data_and_alghoritms.convert_type(exp, nspr.property.parameters[i].type); - nspr.fact_parametres.AddElement(exp); - } - } - } - switch (mot) - { - case motivation.expression_evaluation: - case motivation.semantic_node_reciving: - { - function_node fn = nspr.property.get_function; - if (fn == null) - { - AddError(new ThisPropertyCanNotBeReaded(nspr.property, loc)); - } - base_function_call bfc = create_not_static_method_call(fn, nspr.expression, loc, false); - bfc.parameters.AddRange(nspr.fact_parametres); - if (nspr.property.parameters.Count != 0) - { - return_value(bfc); - return; - } - indexer_as_expression_index(bfc, parameters, mot, loc); - return; - } - case motivation.address_receiving: - { - if (nspr.property.parameters.Count != 0) - { - return_addressed_value(nspr); - return; - } - function_node fn = nspr.property.get_function; - if (fn == null) - { - AddError(new ThisPropertyCanNotBeReaded(nspr.property, loc)); - } - base_function_call bfc = create_not_static_method_call(fn, nspr.expression, loc, false); - bfc.parameters.AddRange(nspr.fact_parametres); - indexer_as_expression_index(bfc, parameters, mot, loc); - return; - } - } - throw new CompilerInternalError("Unsupported motivation"); - } - - public override void visit(SyntaxTree.indexer _indexer) - { - //SSM 11/02/16 - нет, это глупость - /*if (_indexer.dereferencing_value is SyntaxTree.question_colon_expression) // то разбросать индекс по компонентам - { - var q = _indexer.dereferencing_value as SyntaxTree.question_colon_expression; - var nodeToVisit = new SyntaxTree.question_colon_expression(q.condition, new indexer(q.ret_if_true as addressed_value, _indexer.indexes, _indexer.source_context), - new indexer(q.ret_if_false as addressed_value, _indexer.indexes, _indexer.source_context), _indexer.source_context); - visit(nodeToVisit); - return; - }*/ - //end SSM 11/02/16 - - // SSM 18.08.16 - пробуем обработать захват enn[i] в yieldах где enn - поле класса и нуждается в переименовании - // Так же ниже делает lroman - if (_indexer.dereferencing_value is yield_unknown_ident) - { - var yui = (yield_unknown_ident)_indexer.dereferencing_value; - var av = ProcessUnknownIdent(yui); - var nodeToVisit = new indexer(av,_indexer.indexes); - visit(nodeToVisit); - return; - } - - //lroman - if (_indexer.dereferencing_value is closure_substituting_node) - { - var nodeToVisit = new indexer(((closure_substituting_node) _indexer.dereferencing_value).substitution, - _indexer.indexes); - visit(nodeToVisit); - return; - } - - var mot = motivation_keeper.motivation; - motivation_keeper.reset(); - SyntaxTree.ident idi = _indexer.dereferencing_value as SyntaxTree.ident; - if (idi != null) - { - List sil = context.find(idi.name); - if (sil == null) - { - AddError(new UndefinedNameReference(idi.name, get_location(idi))); - } - if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.type_node) - { - indexer_as_type_indexes((type_node)sil.FirstOrDefault().sym_info, _indexer.indexes, mot, get_location(idi)); - return; - } - if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.property_node) - { - property_node pn = (property_node)sil.FirstOrDefault().sym_info; - if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - static_property_reference spr = new static_property_reference(pn, get_location(idi)); - indexer_as_property_indexes(spr, _indexer.indexes, mot, get_location(idi)); - return; - } - else - { - this_node thisnode = new this_node(pn.comprehensive_type, get_location(_indexer)); - location loc111 = get_location(idi); - non_static_property_reference nspr = new non_static_property_reference(pn, thisnode, loc111); - indexer_as_property_indexes(nspr, _indexer.indexes, mot, loc111); - return; - } - } - expression_node en = ident_value_reciving(sil, idi); - - indexer_as_expression_index(en, _indexer.indexes, mot, get_location(idi)); - return; - } - else - { - SyntaxTree.dot_node dotnd = _indexer.dereferencing_value as SyntaxTree.dot_node; - if (dotnd != null) - { - SyntaxTree.ident id = dotnd.right as SyntaxTree.ident; - semantic_node sn = convert_semantic_strong(dotnd.left); - switch (sn.general_node_type) - { - case general_node_type.type_node: - { - type_node ttp = (type_node)sn; - List sil = ttp.find_in_type(id.name, context.CurrentScope); - if (sil == null) - { - AddError(new UndefinedNameReference(id.name, get_location(id))); - } - if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.property_node) - { - property_node pn = (property_node)sil.FirstOrDefault().sym_info; - static_property_reference spr = new static_property_reference(pn, get_location(id)); - indexer_as_property_indexes(spr, _indexer.indexes, mot, get_location(dotnd)); - return; - } - expression_node exp1 = create_static_expression(ttp, id, sil); - indexer_as_expression_index(exp1, _indexer.indexes, mot, get_location(id)); - return; - } - case general_node_type.namespace_node: - case general_node_type.unit_node: - { - List sil = null; - if (sn is namespace_node) - { - sil = ((namespace_node)sn).find(id.name); - } - else - { - sil = ((unit_node)sn).find_only_in_namespace(id.name); - } - if (sil == null) - { - AddError(new UndefinedNameReference(id.name, get_location(id))); - } - location lloc = get_location(id); - if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.type_node) - { - type_node tn = (type_node)sil.FirstOrDefault().sym_info; - indexer_as_type_indexes(tn, _indexer.indexes, mot, lloc); - return; - } - expression_node exp2 = ident_value_reciving(sil, id); - indexer_as_expression_index(exp2, _indexer.indexes, mot, get_location(id)); - return; - } - case general_node_type.expression: - { - expression_node ex = (expression_node)sn; - List sil = ex.type.find_in_type(id.name, context.CurrentScope); - if (sil == null) - { - AddError(new UndefinedNameReference(id.name, get_location(id))); - } - if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.property_node) - { - property_node pn = (property_node)sil.FirstOrDefault().sym_info; - if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - AddError(new CanNotReferenceToStaticPropertyWithExpression(pn, get_location(dotnd), ex.type)); - } - location lloc11 = get_location(dotnd); - try_convert_typed_expression_to_function_call(ref ex); - non_static_property_reference nspr = new non_static_property_reference(pn, ex, lloc11); - indexer_as_property_indexes(nspr, _indexer.indexes, mot, lloc11); - return; - } - expression_node en2 = expression_value_reciving(id, sil, ex, false); - indexer_as_expression_index(en2, _indexer.indexes, mot, get_location(id)); - return; - } - } - } - else - { - expression_node expr = convert_strong(_indexer.dereferencing_value); - indexer_as_expression_index(expr, _indexer.indexes, mot, get_location(_indexer.dereferencing_value)); - return; - } - } - } - - public override void visit(SyntaxTree.roof_dereference _roof_dereference) - { - expression_node exp = null; - var mot = motivation_keeper.motivation; - motivation_keeper.reset(); - - exp = convert_strong(_roof_dereference.dereferencing_value); - if (exp is typed_expression) exp = convert_typed_expression_to_function_call(exp as typed_expression); - //Check this expression - ref_type_node rtn = exp.type as ref_type_node; - //TODO: Сделать нормальное сообщение об ошибке. - if (rtn == null) - { - AddError(get_location(_roof_dereference.dereferencing_value), "CANNOT_DEREFER_THIS_EXPR_OF_NON_POINTER_TYPE"); - } - if (rtn.pointed_type == null) - AddError(get_location(_roof_dereference.dereferencing_value), "TYPE_{0}_IS_NOT_DETERMINED_COMPLETELY", rtn.PointedTypeName); - dereference_node res = new dereference_node(exp, get_location(_roof_dereference)); - switch (mot) - { - case motivation.address_receiving: return_addressed_value(res); break; - case motivation.expression_evaluation: return_value(res); break; - case motivation.semantic_node_reciving: return_semantic_value(res); break; - } - return; - } - - public override void visit(SyntaxTree.dereference _dereference) - { - throw new NotSupportedError(get_location(_dereference)); - } - - public override void visit(SyntaxTree.expression_list _expression_list) - { - //throw new NotSupportedError(get_location(_expression_list)); - int count = _expression_list.expressions.Count; - statement_node_list snl = new statement_node_list(); - for (int i = 0; i < count - 1; i++) - { - statement_node sn = ret.visit(_expression_list.expressions[i]); - snl.AddElement(sn); - } - expression_node ex = ret.visit(_expression_list.expressions[count - 1]); - statements_expression_node sen = new statements_expression_node( - snl, ex, get_location(_expression_list)); - return_value(sen); - } - - public override void visit(SyntaxTree.string_const _string_const) - { - expression_node en = null; - if (_string_const.Value.Length != 1) - { - en = new string_const_node(_string_const.Value, get_location(_string_const)); - if (SemanticRules.GenerateNativeCode && SemanticRules.StringType != null) - en.type = SemanticRules.StringType; - } - else - en = new char_const_node(Convert.ToChar(_string_const.Value), get_location(_string_const)); - - - return_value(en); - } - - public override void visit(SyntaxTree.program_name _program_name) - { - throw new NotSupportedError(get_location(_program_name)); - } - - public override void visit(SyntaxTree.program_tree _program_tree) - { - _program_tree.compilation_units[0].visit(this); - } - - public override void visit(SyntaxTree.declarations _subprogram_definitions) - { - if (SemanticRules.OrderIndependedTypeNames) - { - foreach (SyntaxTree.declaration sd in _subprogram_definitions.defs) - { - if (sd is SyntaxTree.type_declaration) - { - convertion_data_and_alghoritms.check_node_parser_error(sd); - sd.visit(this); - } - } - } - List namespaces = new List(); - foreach (SyntaxTree.declaration sd in _subprogram_definitions.defs) - { - convertion_data_and_alghoritms.check_node_parser_error(sd); - if (sd is syntax_namespace_node) - namespaces.Add(sd as syntax_namespace_node); - } - if (namespaces.Count > 0) - convert_pabc_namespaces(namespaces.ToArray()); - foreach (SyntaxTree.declaration sd in _subprogram_definitions.defs) - { - convertion_data_and_alghoritms.check_node_parser_error(sd); - if (!(sd is syntax_namespace_node)) - sd.visit(this); - } - if (SemanticRules.OrderIndependedFunctionNames) - { - visit_function_realizations(_subprogram_definitions); - context.clear_member_bindings(); - } - } - - public override void visit(SyntaxTree.declaration _subprogram_definition) - { - throw new NotSupportedError(get_location(_subprogram_definition)); - } - - private SyntaxTree.expression get_possible_array_const(SyntaxTree.expression expr, type_node tn, int rank) - { - try - { - if (tn == null) - return expr; - if (rank == 0) - return get_possible_array_const(expr, tn.element_type); - if (expr is SyntaxTree.bracket_expr) - { - SyntaxTree.array_const arr = new SyntaxTree.array_const(); - arr.source_context = expr.source_context; - arr.elements = new SyntaxTree.expression_list(); - arr.elements.expressions.Add(get_possible_array_const((expr as SyntaxTree.bracket_expr).expr, tn.element_type, rank - 1)); - return arr; - } - else if (expr is SyntaxTree.array_const) - { - SyntaxTree.array_const arr = expr as SyntaxTree.array_const; - if (arr.elements != null) - for (int i = 0; i < arr.elements.expressions.Count; i++) - arr.elements.expressions[i] = get_possible_array_const(arr.elements.expressions[i], tn.element_type, rank - 1); - return arr; - } - } - catch - { - - } - return expr; - } - - private SyntaxTree.expression get_possible_array_const(SyntaxTree.expression expr, type_node tn) - { - try - { - if (tn == null) - return expr; - if (expr is SyntaxTree.array_const && tn.BaseFullName != null && tn.BaseFullName.StartsWith("System.Tuple") && tn.type_special_kind != SemanticTree.type_special_kind.array_kind) - { - method_call mc = new method_call(); - mc.parameters = (expr as SyntaxTree.array_const).elements; - mc.dereferencing_value = new dot_node(new ident("Tuple", expr.source_context), new ident("Create", expr.source_context), expr.source_context); - return mc; - } - else if (expr is SyntaxTree.bracket_expr && (tn.type_special_kind == SemanticTree.type_special_kind.array_kind || tn.type_special_kind == SemanticTree.type_special_kind.array_wrapper)) - { - array_internal_interface aii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface; - if (aii != null && aii.rank > 1) - return get_possible_array_const(expr, tn, aii.rank); - SyntaxTree.array_const arr = new SyntaxTree.array_const(); - arr.source_context = expr.source_context; - arr.elements = new SyntaxTree.expression_list(); - arr.elements.expressions.Add(get_possible_array_const((expr as SyntaxTree.bracket_expr).expr, tn.element_type)); - return arr; - } - else if (expr is SyntaxTree.array_const && (tn.type_special_kind == SemanticTree.type_special_kind.array_kind || tn.type_special_kind == SemanticTree.type_special_kind.array_wrapper)) - { - array_internal_interface aii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface; - if (aii != null && aii.rank > 1) - return get_possible_array_const(expr, tn, aii.rank); - SyntaxTree.array_const arr = expr as SyntaxTree.array_const; - if (arr.elements != null) - for (int i = 0; i < arr.elements.expressions.Count; i++) - arr.elements.expressions[i] = get_possible_array_const(arr.elements.expressions[i], tn.element_type); - return arr; - } - else if (expr is SyntaxTree.record_const && tn is common_type_node) - { - common_type_node ctn = tn as common_type_node; - SyntaxTree.record_const rec = expr as SyntaxTree.record_const; - for (int i = 0; i < rec.rec_consts.Count; i++) - { - if (i < ctn.fields.Count) - rec.rec_consts[i].val = get_possible_array_const(rec.rec_consts[i].val, ctn.fields[i].type); - } - return rec; - } - } - catch - { - - } - return expr; - } - - public override void visit(SyntaxTree.var_def_statement _var_def_statement) - { - if (_var_def_statement.vars_type != null && _var_def_statement.vars_type is procedure_header) - { - var ph = _var_def_statement.vars_type as procedure_header; - if (ph.parameters != null) - foreach (var x in ph.parameters.params_list) - { - if (x.inital_value != null) - AddError(get_location(x.inital_value), "DEFAULT_PARAMS_IN_DELEGATE_TYPE"); // SSM bug fix #1463 - } - - } - - if (_var_def_statement.vars_type == null && _var_def_statement.inital_value is SyntaxTree.function_lambda_definition fld) - { - if (fld.formal_parameters != null && fld.formal_parameters.params_list.Select(x => x.vars_type).Any(x=>x is lambda_inferred_type)) - AddError(get_location(_var_def_statement.inital_value), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA"); - if (fld.return_type is lambda_inferred_type) - AddError(get_location(_var_def_statement.inital_value), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA"); - if (fld.return_type == null) - _var_def_statement.vars_type = new procedure_header(fld.formal_parameters, null, null, false, false, null, null, _var_def_statement.source_context); - else - _var_def_statement.vars_type = new function_header(fld.formal_parameters, null, null, null, fld.return_type, _var_def_statement.source_context); - //else - // AddError(get_location(_var_def_statement.inital_value), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA"); //lroman// - } - - - if (_var_def_statement.vars_type == null && _var_def_statement.inital_value is SyntaxTree.pascal_set_constant pc) - { - if (pc.values==null || pc.values.Count == 0) - AddError(get_location(_var_def_statement.inital_value), "IMPOSSIBLE_TO_INFER_SET_TYPE"); - } - - - bool is_event = _var_def_statement.is_event; - - if (context.converting_block() == block_type.type_block && - context.converted_type.IsInterface && !is_event) - { - AddError(get_location(_var_def_statement), "INVALID_INTERFACE_MEMBER"); - } - - if (is_event && context.converting_block() == block_type.type_block && context.converted_type.IsInterface && (_var_def_statement.vars_type is function_header || _var_def_statement.vars_type is procedure_header)) - AddError(get_location(_var_def_statement.vars_type), "ANONYMOUS_DELEGATE_IN_INTERFACE_NOT_ALLOWED"); - - type_node tn = null; - expression_node inital_value = null; - if (_var_def_statement.vars_type != null) - { - tn = convert_strong(_var_def_statement.vars_type); - - if (tn.type_special_kind != SemanticTree.type_special_kind.array_kind && - tn.type_special_kind != SemanticTree.type_special_kind.array_wrapper && - !tn.BaseFullName.StartsWith("System.Tuple") && - _var_def_statement.inital_value is SyntaxTree.array_const ac) - { - AddError(get_location(_var_def_statement), "IMPOSSIBLE_TO_CONVERT_ARRAY_CONST_TO_{0}", tn); - } - - //LambdaHelper.InferTypesFromVarStmt(tn, _var_def_statement.inital_value as SyntaxTree.function_lambda_definition, this); //lroman// - if (tn.IsStatic && _var_def_statement.vars.idents[0].name != YieldHelpers.YieldConsts.Self) // SSM 10/07/19 fix #1639 в статическом классе можно только фиктивное поле с именем YieldHelpers.YieldConsts.Self описать - для того чтобы посмотреть на семантике его тип!!! - AddError(get_location(_var_def_statement), "VARIABLES_OF_STATIC_CLASS_NOT_ALLOWED"); - var fld1 = _var_def_statement.inital_value as SyntaxTree.function_lambda_definition; - if (fld1 != null) - { - MaybeConvertFunctionLambdaDefinitionToProcedureLambdaDefinition(fld1); - LambdaHelper.InferTypesFromVarStmt(tn, fld1, this); //lroman// - fld1.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //SSM 12.2017 - } - - ref_type_node rt = tn as ref_type_node; - if (rt != null) - { - if (type_section_converting) - { - RefTypesForCheckPointersTypeForDotNetFramework.Add(rt); - } - else - { - CheckPointersTypeForDotNetFramework(rt.pointed_type, get_location(_var_def_statement.vars_type)); - } - } - if (is_event && !tn.IsDelegate) - AddError(get_location(_var_def_statement.vars_type), "EVENT_TYPE_MUST_BE_DELEGATE"); - check_for_type_allowed(tn,get_location(_var_def_statement.vars_type)); - if (_var_def_statement.vars_type is function_header || _var_def_statement.vars_type is procedure_header) - check_delegate_on_generic_parameters(tn as common_type_node, get_location(_var_def_statement.vars_type)); - if (context.converting_block() == block_type.type_block && context.converted_type.is_value_type && _var_def_statement.var_attr != SyntaxTree.definition_attribute.Static) - CheckForCircuralInRecord(tn, get_location(_var_def_statement.vars_type)); - if (_var_def_statement.inital_value != null) - if (is_event) AddError(new NotSupportedError(get_location(_var_def_statement.inital_value))); - else - { - _var_def_statement.inital_value = get_possible_array_const(_var_def_statement.inital_value,tn); - var ivc = convert_strong(_var_def_statement.inital_value); - inital_value = convert_strong_to_constant_or_function_call_for_varinit(ivc, tn); - if (!tn.IsDelegate && tn != SystemLibrary.SystemLibrary.object_type && inital_value is typed_expression && _var_def_statement.inital_value is addressed_value) - { - method_call mc = new method_call(); - mc.dereferencing_value = _var_def_statement.inital_value as addressed_value; - ivc = convert_strong(mc); - inital_value = convert_strong_to_constant_or_function_call_for_varinit(ivc, tn); - } - } - } - else - { - if (is_event) - AddError(get_location(_var_def_statement), "EVENT_MUST_HAVE_TYPE"); - var ex = convert_strong(_var_def_statement.inital_value); - expression_node cn = convert_strong_to_constant_or_function_call_for_varinit(ex); - if (cn is constant_node) - (cn as constant_node).SetType(DeduceType(cn.type, get_location(_var_def_statement.inital_value))); - inital_value = cn; - tn = inital_value.type; - if (tn is null_type_node) - AddError(cn.location, "CAN_NOT_DEDUCE_TYPE_{0}", tn.name); - if (context.converting_block() == block_type.type_block && context.converted_type.is_value_type && _var_def_statement.var_attr != SyntaxTree.definition_attribute.Static) - CheckForCircuralInRecord(tn, get_location(_var_def_statement)); - } - if (inital_value != null && inital_value is typed_expression) - { - inital_value = convert_typed_expression_to_function_call(inital_value as typed_expression); - tn = inital_value.type; - if (inital_value is typed_expression) - { - base_function_call bfc = ((inital_value as typed_expression).type as delegated_methods).proper_methods[0]; - if (bfc.function.is_generic_function && _var_def_statement.vars_type == null) - { - AddError(inital_value.location, "CAN_NOT_DEDUCE_TYPE_{0}", null); - } - foreach (parameter p in bfc.simple_function_node.parameters) - { - if (p.type.is_generic_parameter) - AddError(inital_value.location, "USE_ANONYMOUS_FUNCTION_TYPE_WITH_GENERICS"); - } - common_type_node del = - convertion_data_and_alghoritms.type_constructor.create_delegate(context.get_delegate_type_name(), bfc.simple_function_node.return_value_type, bfc.simple_function_node.parameters, context.converted_namespace, null); - context.converted_namespace.types.AddElement(del); - tn = del; - inital_value = convertion_data_and_alghoritms.explicit_convert_type(inital_value, del); - inital_value.type = tn; - } - else if (inital_value is base_function_call) - { - base_function_call bfc = inital_value as base_function_call; - if (bfc.function.is_generic_function && _var_def_statement.vars_type == null) - { - AddError(inital_value.location, "CAN_NOT_DEDUCE_TYPE_{0}", null); - } - } - } - foreach (SyntaxTree.ident id in _var_def_statement.vars.idents) - { - location lid = get_location(id); - SemanticTree.polymorphic_state ps = SemanticTree.polymorphic_state.ps_common; - if (_var_def_statement.var_attr == SyntaxTree.definition_attribute.Static) - ps = SemanticTree.polymorphic_state.ps_static; - if (!is_event) - { - var_definition_node vdn = context.add_var_definition(id.name, lid, ps); - assign_doc_info(vdn,_var_def_statement); - if (_var_def_statement.attributes != null) - { - make_attributes_for_declaration(_var_def_statement, vdn); - } - } - else - { - event_node ce = null; - if (context.converted_type != null && context.converted_type.IsInterface) - ps = SemanticTree.polymorphic_state.ps_virtual_abstract; - if (context.converted_type != null) - ce = context.add_event_definition(id.name, lid, tn, ps, context.converted_type.IsInterface); - else if (context.top_function == null) - ce = context.add_namespace_event(id.name, lid, tn); - else - AddError(lid, "EVENT_MUST_BE_IN_CLASS_OR_NAMESPACE"); - assign_doc_info(ce,_var_def_statement); - if (_var_def_statement.attributes != null) - { - make_attributes_for_declaration(_var_def_statement, ce); - } - } - } - if (context.converted_type != null && context.converting_block() == block_type.type_block && context.converted_type.IsStatic && _var_def_statement.var_attr != definition_attribute.Static) - AddError(get_location(_var_def_statement), "STATIC_CLASSES_CANNOT_NON_STATIC_MEMBERS"); - if (is_event) return; - context.save_var_definitions(); - - context.restore_var_definitions(); - context.close_var_definition_list(tn, inital_value); - if (!SemanticRules.ManyVariablesOneInitializator && _var_def_statement.inital_value != null && _var_def_statement.vars.idents.Count > 1) - AddError(get_location(_var_def_statement.inital_value), "ONE_VARIABLE_ONE_INITIALIZATOR"); - } - - private void CheckForCircularityInPointers(ref_type_node left, type_node right, location loc) - { - if (left == null || right == null) - return; - if (left == right) - // #ErrorRefactoringProblem - // AddError(loc, "CIRCULARITY_IN_POINTER"); // Если заменить этой строкой следующую, то при запуске bin\TestRunner.exe это приложение зацикливается, что сопровождается утечкой памяти - AddError(new CircuralityInPointer(loc)); - if (right is ref_type_node) - CheckForCircularityInPointers(left, (right as ref_type_node).pointed_type, loc); - else if (right.type_special_kind == SemanticTree.type_special_kind.array_kind || right.type_special_kind == SemanticTree.type_special_kind.array_wrapper) - CheckForCircularityInPointers(left,right.element_type,loc); - } - - private void CheckForCircuralInRecord(type_node tn, location loc) - { - if (tn == context.converted_type || tn.original_generic == context.converted_type) - { - AddError(loc, "CIRCULARITY_IN_RECORD"); - } - if (tn is common_type_node) - { - common_type_node ctn = tn as common_type_node; - if (ctn.is_value_type) - { - foreach (class_field fld in ctn.fields) - if (fld.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - CheckForCircuralInRecord(fld.type, loc); - } - else - { - foreach (class_field fld in ctn.fields) - if (fld.polymorphic_state != SemanticTree.polymorphic_state.ps_static && fld.type is simple_array) - CheckForCircuralInRecord((fld.type as simple_array).element_type, loc); - } - } - } - - //Пытается вывести тип - private type_node DeduceType(type_node tn, location loc) - { - if (tn is undefined_type || tn is null_type_node) - { - if (tn is ArrayConstType) - return convertion_data_and_alghoritms.type_constructor.create_unsized_array((tn as ArrayConstType).element_type, context.converted_namespace, 1, loc); - AddError(loc, "CAN_NOT_DEDUCE_TYPE_{0}", tn.name); - } - return tn; - } - - public override void visit(SyntaxTree.ident_list _ident_list) - { - throw new NotSupportedError(get_location(_ident_list)); - } - - public override void visit(SyntaxTree.variable_definitions _variable_definitions) - { - bool is_event = false; - foreach (SyntaxTree.var_def_statement vds in _variable_definitions.var_definitions) - { - convertion_data_and_alghoritms.check_node_parser_error(vds); - if (vds.is_event && !is_event) - is_event = true; - else if (is_event) - vds.is_event = true; - vds.visit(this); - } - } - - public override void visit(SyntaxTree.named_type_reference _named_type_reference) - { - var loc = get_location(_named_type_reference); - type_node tn = find_type(_named_type_reference, loc); - return_value(tn); - } - - public override void visit(SyntaxTree.type_definition _type_definition) - { - throw new NotSupportedError(get_location(_type_definition)); - } - - public override void visit(SyntaxTree.addressed_value _addressed_value) - { - throw new NotSupportedError(get_location(_addressed_value)); - } - - private addressed_expression ident_address_reciving(SymbolInfo si, SyntaxTree.ident _ident) - { - location lloc = get_location(_ident); - definition_node dn = null; - if (!internal_is_assign) - dn = context.check_name_node_type(_ident.name, si, lloc, - general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node); - else - dn = context.check_name_node_type(_ident.name, si, lloc, - general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node, general_node_type.constant_definition); - if (dn.general_node_type == general_node_type.constant_definition) - AddError(get_location(_ident), "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT"); - switch (dn.general_node_type) - { - case general_node_type.variable_node: - { - local_variable lv = dn as local_variable; - if (lv != null && (lv.function is common_method_node)) - { - //self variable - if ((lv.function as common_method_node).self_variable == lv) - { - AddError(lloc, "VARIABLE_{0}_READONLY", lv.name); - } - } - return create_variable_reference(dn, lloc); - } - case general_node_type.property_node: - { - property_node pn = (property_node)dn; - if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - static_property_reference spr = new static_property_reference(pn, lloc); - return spr; - } - //this_node thisnode=new this_node(context.converted_type,lloc); - if (pn.comprehensive_type.Scope == null && pn is compiled_property_node) - (pn.comprehensive_type as compiled_type_node).init_scope(); - non_static_property_reference nspr = new non_static_property_reference(pn, GetCurrentObjectReference(pn.comprehensive_type.Scope, pn, lloc), lloc); - return nspr; - } - case general_node_type.event_node: - { - if (dn.semantic_node_type == semantic_node_type.compiled_event) - { - compiled_event ce = (compiled_event)dn; - if (ce.is_static) - { - static_event_reference ser = new static_event_reference(ce, get_location(_ident)); - return ser; - } - nonstatic_event_reference nser = new nonstatic_event_reference( - GetCurrentObjectReference(ce.comprehensive_type.Scope, ce, lloc), ce, lloc); - return nser; - } - else if (dn.semantic_node_type == semantic_node_type.common_event) - { - common_event ce = (common_event)dn; - if (ce.is_static) - { - static_event_reference ser = new static_event_reference(ce, get_location(_ident)); - return ser; - } - nonstatic_event_reference nser = new nonstatic_event_reference( - GetCurrentObjectReference(ce.comprehensive_type.Scope, ce, lloc), ce, lloc); - return nser; - } - else if (dn.semantic_node_type == semantic_node_type.common_namespace_event) - { - common_namespace_event cne = (common_namespace_event)dn; - static_event_reference ser = new static_event_reference(cne, get_location(_ident)); - return ser; - } - break; - } - } - return null; - } - - private expression_node ident_value_reciving(List sil, SyntaxTree.ident _ident) - { - //SymbolInfo si=blocks.find(_ident.name); - location lloc = get_location(_ident); - definition_node dn = context.check_name_node_type(_ident.name, sil?.FirstOrDefault(), get_location(_ident), general_node_type.variable_node, - general_node_type.function_node, general_node_type.property_node, general_node_type.constant_definition, - general_node_type.event_node); - switch (dn.general_node_type) - { - case general_node_type.constant_definition: - { - constant_definition_node cdn = (constant_definition_node)dn; - if (cdn.const_value is array_const || cdn.const_value is record_constant || cdn.const_value is common_namespace_function_call_as_constant) - { - return create_constant_reference(cdn,lloc); - } - if (cdn.const_value == null) - AddError(new UndefinedNameReference(cdn.name,get_location(_ident))); - constant_node cn = cdn.const_value.get_constant_copy(get_location(_ident)); - if (cn != null) return cn; - return cdn.const_value; - } - case general_node_type.variable_node: - { - local_variable lv = dn as local_variable; - if (lv != null && (lv.function is common_method_node)) - { - //self variable - if ((lv.function as common_method_node).self_variable == lv) - //return new this_node((lv.function as common_method_node).cont_type, lloc); - return new this_node(lv.type, lloc); - //return GetCurrentObjectReference((lv.function as common_method_node).cont_type.Scope, lloc); - } - return create_variable_reference(dn, lloc); - } - case general_node_type.function_node: - { - //return convertion_data_and_alghoritms.create_full_function_call(new expressions_list(), - // si,lloc,blocks.converted_type,blocks.top_function,false); - if (SystemUnitAssigned && SystemLibrary.SystemLibInitializer.PascalABCVersion.Equal(sil)) - { - return new string_const_node(RevisionClass.FullVersion, get_location(_ident)); - } - if (sil.FirstOrDefault().sym_info == SystemLibrary.SystemLibInitializer.NewProcedure.sym_info) - { - AddError(lloc, "EXPECTED_TYPE_AFTER_NEW"); - } - if (sil.FirstOrDefault().sym_info == SystemLibrary.SystemLibInitializer.DisposeProcedure.sym_info) - { - AddError(lloc, "CANNOT_GET_POINTER_TO_DISPOSE"); - } - if (sil.FirstOrDefault().sym_info is common_method_node && (sil.FirstOrDefault().sym_info as common_method_node).is_constructor) - return convertion_data_and_alghoritms.create_full_function_call(new expressions_list(), - sil, lloc, context.converted_type, context.top_function, false); - if (!(sil.FirstOrDefault().sym_info is common_in_function_function_node)) - { - var ex = sil.FirstOrDefault().sym_info as basic_function_node; - if (ex != null && ex.name.ToLower() == "exit") - return new basic_function_call(ex, ex.location); - return make_delegate_wrapper(null, sil, lloc, ((sil.FirstOrDefault().sym_info is common_method_node) && ((common_method_node)sil.FirstOrDefault().sym_info).IsStatic)); - } - return convertion_data_and_alghoritms.create_full_function_call(new expressions_list(), - sil, lloc,context.converted_type,context.top_function,false); - } - case general_node_type.property_node: - { - property_node pn = (property_node)dn; - function_node fn = pn.get_function; - if (fn == null) - { - AddError(new ThisPropertyCanNotBeReaded(pn, lloc)); - } - if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - return create_static_method_call(fn, lloc, pn.comprehensive_type, false); - } - check_property_no_params(pn, lloc); - //this_node thisnode = new this_node(context.converted_type, lloc); - if (pn.comprehensive_type.Scope == null && pn is compiled_property_node) - (pn.comprehensive_type as compiled_type_node).init_scope(); - return create_not_static_method_call(fn, GetCurrentObjectReference(pn.comprehensive_type.Scope, fn, lloc), lloc, false); - } - case general_node_type.event_node: - { - if (dn.semantic_node_type == semantic_node_type.compiled_event) - { - compiled_event ce = (compiled_event)dn; - if (ce.is_static) - { - static_event_reference ser = new static_event_reference(ce, get_location(_ident)); - return ser; - } - nonstatic_event_reference nser = new nonstatic_event_reference( - new this_node(context.converted_type, lloc), ce, lloc); - return nser; - } - else if (dn.semantic_node_type == semantic_node_type.common_event) - { - common_event ce = (common_event)dn; - if (ce.is_static) - { - static_event_reference ser = new static_event_reference(ce, get_location(_ident)); - return ser; - } - nonstatic_event_reference nser = new nonstatic_event_reference( - new this_node(context.converted_type, lloc), ce, lloc); - return nser; - } - else if (dn.semantic_node_type == semantic_node_type.common_namespace_event) - { - common_namespace_event cne = (common_namespace_event)dn; - if (_compiled_unit.namespaces.IndexOf(cne.namespace_node) != -1) - { - static_event_reference ser = new static_event_reference(cne, get_location(_ident)); - return ser; - } - else - AddError(get_location(_ident), "EVENT_{0}_MUST_BE_IN_LEFT_PART", cne.name); - } - break; - } - } - return null; - } - - private expression_node create_constant_reference(constant_definition_node cdn, location loc) - { - if (cdn is namespace_constant_definition) - return new namespace_constant_reference(cdn as namespace_constant_definition,loc); - else if (cdn is function_constant_definition) - return new function_constant_reference(cdn as function_constant_definition,loc); - else - return cdn.const_value; - } - - private List find_in_base(SyntaxTree.inherited_message ident) - { - if (context.converted_type == null) - { - AddError(get_location(ident), "INHERITED_EXPECTED_IN_CLASS"); - } - if (context.converted_type.base_type == null) - { - AddError(get_location(ident), "NO_BASE_CLASS_DEFINED_BUT_INHERITED_MEET"); - } - common_method_node cmn = context.converted_func_stack.first() as common_method_node; - if (cmn == null) - { - AddError(get_location(ident), "NAME_IN_BASE_CLASS_MUST_BE_METHOD"); - } - - List sil = null; - if (cmn.is_constructor) - sil = context.converted_type.base_type.find_in_type(compiler_string_consts.default_constructor_name, context.CurrentScope); - else - sil = context.converted_type.base_type.find_in_type(cmn.name, context.CurrentScope); - if (sil != null) - { - while (sil.Count != 0) - { - if (!cmn.is_constructor) - { - if (sil.FirstOrDefault().sym_info is function_node && convertion_data_and_alghoritms.function_eq_params_and_result(sil.FirstOrDefault().sym_info as function_node, cmn)) - return sil; - } - else - { - if (sil.FirstOrDefault().sym_info is function_node && convertion_data_and_alghoritms.function_eq_params(sil.FirstOrDefault().sym_info as function_node, cmn)) - return sil; - } - sil.RemoveAt(0); - } - sil = null; - } - if (cmn.is_constructor) - AddError(get_location(ident), "NO_CONSTRUCTOR_IN_BASE_CLASS_WITH_SAME_PARAMETERS"); - else - AddError(get_location(ident), "NAME_IN_BASE_CLASS_MUST_BE_METHOD"); - return sil; - /*if (si == null) - { - throw new UndefinedNameReference(name, get_location(ident)); - } - if (!(si.sym_info is common_method_node) && !(si.sym_info is compiled_function_node)) - { - throw new NameInBaseClassMustBeMethod(name, get_location(ident)); - } - common_function_node cfn = si.sym_info as common_function_node;*/ - } - - private List find_in_base(SyntaxTree.inherited_ident ident) - { - if (context.converted_type == null) - { - AddError(get_location(ident), "INHERITED_EXPECTED_IN_CLASS"); - } - if (context.converted_type.base_type == null) - { - AddError(get_location(ident), "NO_BASE_CLASS_DEFINED_BUT_INHERITED_MEET"); - } - List sil = context.converted_type.base_type.find_in_type(ident.name, context.CurrentScope); - if (sil == null) - { - sil = context.converted_namespace.find(ident.name); - if (sil != null) - AddError(get_location(ident), "CLASS_MEMBER_{0}_EXPECTED", ident.name); - else - AddError(new UndefinedNameReference(ident.name, get_location(ident))); - } - return sil; - } - - private addressed_expression inherited_ident_address_reciving(SyntaxTree.inherited_ident _ident) - { - List sil = find_in_base(_ident); - return ident_address_reciving(sil?.FirstOrDefault(), _ident); - } - - private addressed_expression ident_address_reciving(SyntaxTree.ident _ident) - { - if ((context.converting_block() == block_type.function_block) && (context.top_function.return_variable != null)) - { - List sil = context.top_function.scope.FindOnlyInScope(_ident.name); // почему-то не находит локальную переменную с этим именем - // тут баг #2401 - // context.find_only_in_namespace(_ident.name); // это было закомментировано 10.01.21 - if (sil == null) - { - int comp = SystemLibrary.SystemLibrary.string_comparer.Compare(_ident.name, context.top_function.name); - if (comp == 0) // мы нашли функцию и ее имя совпадает с ident - { - List mysi = context.find(_ident.name); - if (mysi != null && mysi[0].sym_info is function_node) - { - local_variable lv = context.top_function.return_variable; - return new local_variable_reference(lv, 0, get_location(_ident)); - } - } - } - } - List idsi = context.find(_ident.name); - - return ident_address_reciving(idsi?.FirstOrDefault(), _ident); - } - - internal addressed_expression create_variable_reference(definition_node dn, location lloc) - { - switch (dn.semantic_node_type) - { - case semantic_node_type.local_variable: - { - local_variable lv = (local_variable)dn; - if (context.converting_block() == block_type.function_block) - { - return new local_variable_reference(lv, - convertion_data_and_alghoritms.symbol_table.GetRelativeScopeDepth(lv.function.scope, context.top_function.scope), lloc); - } - else if (context.converting_block() == block_type.namespace_block) - { - return new local_variable_reference(lv, 0, lloc); - } - else - { - throw new CompilerInternalError("Invalid block type"); - } - } - case semantic_node_type.namespace_variable: - { - namespace_variable nv = (namespace_variable)dn; - return new namespace_variable_reference(nv, lloc); - } - case semantic_node_type.class_field: - { - class_field cf = (class_field)dn; - if (cf.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - { - return new static_class_field_reference(cf, lloc); - } - expression_node obj = GetCurrentObjectReference(cf.cont_type.Scope,cf, lloc); //new this_node(context.converted_type, lloc); - return new class_field_reference(cf, obj, lloc); - } - case semantic_node_type.common_parameter: - { - if (context.in_parameters_block) - AddError(new ParameterReferenceInDefaultParameterNotAllowed(lloc)); - common_parameter cpar = (common_parameter)dn; - return new common_parameter_reference(cpar, - convertion_data_and_alghoritms.symbol_table.GetRelativeScopeDepth(cpar.common_function.scope, context.top_function.scope), lloc); - } - case semantic_node_type.local_block_variable: - { - return new local_block_variable_reference((local_block_variable)dn, lloc); - } - case semantic_node_type.compiled_variable_definition: - { - compiled_variable_definition cvd = dn as compiled_variable_definition; - if (cvd.polymorphic_state == SemanticTree.polymorphic_state.ps_static) - return new static_compiled_variable_reference(cvd, lloc); - expression_node obj = GetCurrentObjectReference(cvd.cont_type.Scope, cvd, lloc); //new this_node(context.converted_type, lloc); - return new compiled_variable_reference(cvd, obj, lloc); - } - default: throw new NotSupportedError(lloc); - } - return null; - } - - private expression_node ident_value_reciving(SyntaxTree.ident _ident) - { - List sil = context.find(_ident.name); - return ident_value_reciving(sil, _ident); - } - - private expression_node inherited_message_value_reciving(SyntaxTree.inherited_message _ident) - { - List sil = find_in_base(_ident); - bool constr = false; - if (sil != null) - if (sil.FirstOrDefault().sym_info is common_method_node) - { - if ((sil.FirstOrDefault().sym_info as common_method_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) - AddError(get_location(_ident), "CANNOT_CALL_ABSTRACT_METHOD"); - constr = (sil.FirstOrDefault().sym_info as common_method_node).is_constructor; - } - else - if (sil.FirstOrDefault().sym_info is compiled_function_node) - { - if ((sil.FirstOrDefault().sym_info as compiled_function_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) - AddError(get_location(_ident), "CANNOT_CALL_ABSTRACT_METHOD"); - } - else if (sil.FirstOrDefault().sym_info is compiled_constructor_node) - { - constr = true; - } - location loc = get_location(_ident); - function_node fn = sil.FirstOrDefault().sym_info as function_node; - base_function_call bfc = null; - common_function_node cfn = context.converted_func_stack.first(); - int depth = context.converted_func_stack.size-1; - if (!constr) - { - if (fn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - { - bfc = create_not_static_method_call(fn,new this_node(context.converted_type,loc),loc,true); - if (bfc is common_method_call) - (bfc as common_method_call).virtual_call = false; - else - (bfc as compiled_function_call).virtual_call = false; - } - else if (fn is common_method_node) - bfc = create_static_method_call(fn,loc,(fn as common_method_node).cont_type,true); - else if (fn is compiled_function_node) - bfc = create_static_method_call(fn,loc,(fn as compiled_function_node).cont_type,true); - else - throw new NotSupportedError(loc); - } - else - { - if (!context.allow_inherited_ctor_call && !context.can_call_inherited_ctor_call(convertion_data_and_alghoritms.statement_list_stack_first())) - AddError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST"); - expressions_list exprs = new expressions_list(); - foreach (common_parameter cp in cfn.parameters) - { - exprs.AddElement(new common_parameter_reference(cp,depth,loc)); - } - if (fn is common_method_node) - { - common_constructor_call ccc = create_constructor_call((fn as common_method_node).cont_type,exprs,loc) as common_constructor_call; - ccc._new_obj_awaited = false; - return ccc; - } - else if (fn is compiled_constructor_node) - { - compiled_constructor_call ccc = create_constructor_call((fn as compiled_constructor_node).compiled_type,exprs,loc) as compiled_constructor_call; - ccc._new_obj_awaited = false; - return ccc; - } - else - throw new NotSupportedError(loc); - } - - foreach (common_parameter cp in cfn.parameters) - { - bfc.parameters.AddElement(new common_parameter_reference(cp,depth,loc)); - } - return bfc; - } - - private expression_node inherited_ident_value_reciving(SyntaxTree.inherited_ident _ident) - { - List sil = find_in_base(_ident); - if (sil != null) - if (sil.FirstOrDefault().sym_info is common_method_node) - { - if ((sil.FirstOrDefault().sym_info as common_method_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) - AddError(get_location(_ident), "CANNOT_CALL_ABSTRACT_METHOD"); - } - else - if (sil.FirstOrDefault().sym_info is compiled_function_node) - { - if ((sil.FirstOrDefault().sym_info as compiled_function_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) - AddError(get_location(_ident), "CANNOT_CALL_ABSTRACT_METHOD"); - } - return ident_value_reciving(sil, _ident); - } - - - private semantic_node ident_semantic_reciving(SyntaxTree.ident _ident) - { - List si_left = context.find(_ident.name); - return ident_semantic_reciving(si_left, _ident); - } - - private semantic_node inherited_ident_semantic_reciving(SyntaxTree.inherited_ident _ident) - { - List sil = find_in_base(_ident); - return ident_semantic_reciving(sil, _ident); - } - - private semantic_node ident_semantic_reciving(List si_left, SyntaxTree.ident _ident) - { - //SymbolInfo si_left=blocks.find(_ident.name); - location lloc = get_location(_ident); - if (si_left == null) - { - AddError(new UndefinedNameReference(_ident.name, lloc)); - } - definition_node dn = context.check_name_node_type(_ident.name, si_left?.FirstOrDefault(), get_location(_ident), - general_node_type.constant_definition, general_node_type.function_node, - general_node_type.namespace_node, general_node_type.property_node, - general_node_type.type_node, general_node_type.variable_node, - general_node_type.unit_node); - switch (dn.general_node_type) - { - case general_node_type.constant_definition: - case general_node_type.function_node: - case general_node_type.property_node: - case general_node_type.variable_node: - { - return ident_value_reciving(si_left, _ident); - } - case general_node_type.namespace_node: - { - //throw new CompilerInternalError("Unsupported now."); - return dn; - } - case general_node_type.type_node: - { - type_node tn = dn as type_node; - //dot_node_as_type_ident(tn,id_right,mot); - return tn; - } - case general_node_type.unit_node: - { - //throw new CompilerInternalError("Unsupproted now."); - //throw new NotSupportedError(get_location(_ident)); - return dn; - } - } - return null; - } - - public override void visit(SyntaxTree.ident _ident) - { - if (_ident.name.IndexOf('.') != -1) - { - var arr = _ident.name.Split('.'); - var dn = new dot_node(new ident(_ident.name.Substring(0, _ident.name.LastIndexOf('.')), _ident.source_context), new ident(arr[arr.Length - 1], _ident.source_context)); - dn.visit(this); - return; - } - var mot = motivation_keeper.motivation; - motivation_keeper.reset(); - switch (mot) - { - case motivation.address_receiving: return_addressed_value(ident_address_reciving(_ident)); break; - case motivation.expression_evaluation: return_value(ident_value_reciving(_ident)); break; - //case motivation.symbol_info_reciving: return_symbol_value(blocks.find(_ident.name));break; - case motivation.semantic_node_reciving: return_semantic_value(ident_semantic_reciving(_ident)); break; - default: throw new NotSupportedError(get_location(_ident)); - } - return; - } - - public override void visit(SyntaxTree.subprogram_body _subprogram_body) - { - throw new NotSupportedError(get_location(_subprogram_body)); - } - - public override void visit(SyntaxTree.statement _statement) - { - throw new NotSupportedError(get_location(_statement)); - } - - public override void visit(SyntaxTree.double_const _double_const) - { - expression_node en = new double_const_node(_double_const.val, get_location(_double_const)); - var mot = motivation_keeper.motivation; - motivation_keeper.reset(); - switch (mot) - { - case motivation.address_receiving: throw new CompilerInternalError("Addres receiving from constant"); - case motivation.expression_evaluation: return_value(en); break; - case motivation.semantic_node_reciving: return_semantic_value(en); break; - } - //return_value(en); - return; - } - - public override void visit(SyntaxTree.bigint_const bi) - { - var names = new List { new ident("System"), new ident("Numerics"), new ident("BigInteger") }; - var ntr = new named_type_reference(names, bi.source_context); - var ne = new new_expr(ntr, new expression_list(new uint64_const(bi.val)),bi.source_context); - visit(ne); - } - - - public override void visit(SyntaxTree.int32_const int32) - { - - //таблица целых констант на уровне синтаксиса - // - 0 + - // 32--------16----8----|----8----16--------32----------------64(bits) - // [ int64 )[ int32 ]( int64 ]( uint64 ] - - //таблица целых констант на уровне семантики(???) - // - 0 + - // 32--------16----8----|----8----16--------32----------------64(bits) - // [ long )[ int )[byte](int]( long ]( ulong ] - - //Отлюченно временно (из-за ошибок временно алгоритмах выбора оперетора?) - /*if(int32.val>=byte.MinValue && int32.val<=byte.MaxValue) - return_value(new byte_const_node((byte)int32.val, get_location(int32))); - else*/ - expression_node en = null; - /* - if ((int32.val >= byte.MinValue) && (int32.val <= byte.MaxValue)) - { - en = new byte_const_node((byte)int32.val, get_location(int32)); - } - else - { - en = new int_const_node(int32.val, get_location(int32)); - } - */ - en = SystemLibrary.static_executors.make_int_const(int32.val, get_location(int32)); - var mot = motivation_keeper.motivation; - motivation_keeper.reset(); - switch (mot) - { - case motivation.address_receiving: throw new CompilerInternalError("Addres receiving from constant"); - case motivation.expression_evaluation: return_value(en); break; - case motivation.semantic_node_reciving: return_semantic_value(en); break; - } - //return_value(en); - return; - } - - public override void visit(SyntaxTree.int64_const int64) - { - expression_node en = new long_const_node(int64.val, get_location(int64)); - var mot = motivation_keeper.motivation; - motivation_keeper.reset(); - switch (mot) - { - case motivation.address_receiving: throw new CompilerInternalError("Addres receiving from constant"); - case motivation.expression_evaluation: return_value(en); break; - case motivation.semantic_node_reciving: return_semantic_value(en); break; - } - //return_value(en); - return; - } - - public override void visit(SyntaxTree.uint64_const uint64) - { - //TODO добавить обработку - // :-) - //throw new CompilerInternalError("Числа UInt64 доступны только в PascalABC.NET Professional Edition"); - expression_node en = new ulong_const_node(uint64.val, get_location(uint64)); - var mot = motivation_keeper.motivation; - motivation_keeper.reset(); - switch (mot) - { - case motivation.address_receiving: throw new CompilerInternalError("Addres receiving from constant"); - case motivation.expression_evaluation: return_value(en); break; - case motivation.semantic_node_reciving: return_semantic_value(en); break; - } - return; - } - - - public override void visit(SyntaxTree.bool_const _bool_const) - { - expression_node en = new bool_const_node(_bool_const.val, get_location(_bool_const)); - var mot = motivation_keeper.motivation; - motivation_keeper.reset(); - switch (mot) - { - case motivation.address_receiving: throw new CompilerInternalError("Address receiving from constant"); - case motivation.expression_evaluation: return_value(en); break; - case motivation.semantic_node_reciving: return_semantic_value(en); break; - } - //return_value(en); - return; - } - - public override void visit(SyntaxTree.const_node _const_node) - { - throw new NotSupportedError(get_location(_const_node)); - } - - public override void visit(SyntaxTree.un_expr _un_expr) - { - expression_node exp = convert_strong(_un_expr.subnode); - expression_node res = find_operator(_un_expr.operation_type, exp, get_location(_un_expr)); - return_value(res); - } - - public override void visit(SyntaxTree.bin_expr _bin_expr) - { - expression_node left = convert_strong(_bin_expr.left); - expression_node right = convert_strong(_bin_expr.right); - if (_bin_expr.operation_type == Operators.In) - try_convert_typed_expression_to_function_call(ref left); - expression_node res = find_operator(_bin_expr.operation_type, left, right, get_location(_bin_expr)); - - if (res.type is undefined_type) - AddError(get_location(_bin_expr), "OPERATOR_RETURN_TYPE_UNDEFINED_{0}", name_reflector.get_name(_bin_expr.operation_type)); - if (res.type.type_special_kind == SemanticTree.type_special_kind.base_set_type) - { - if (left.type.element_type == right.type.element_type) - res.type = left.type; - else if (type_table.compare_types(left.type, right.type) == type_compare.greater_type) - res.type = left.type; - else if (type_table.compare_types(left.type, right.type) == type_compare.less_type) - res.type = right.type; - else if (type_table.compare_types(left.type, right.type) == type_compare.non_comparable_type) - res.type = context.create_set_type(SystemLibrary.SystemLibrary.object_type, get_location(_bin_expr)); - } - //ssyy, 15.05.2009 - switch (_bin_expr.operation_type) - { - case PascalABCCompiler.SyntaxTree.Operators.Equal: - case PascalABCCompiler.SyntaxTree.Operators.NotEqual: - if (left.type.is_generic_parameter && right.type.is_generic_parameter) - { - compiled_static_method_call cfc = new compiled_static_method_call( - SystemLibrary.SystemLibrary.object_equals_method, get_location(_bin_expr)); - cfc.parameters.AddElement(left); - cfc.parameters.AddElement(right); - if (_bin_expr.operation_type == PascalABCCompiler.SyntaxTree.Operators.NotEqual) - { - res = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node, get_location(_bin_expr), cfc); - } - else - { - res = cfc; - } - } - else if (left is static_event_reference) - { - if ((left as static_event_reference).en is compiled_event) - AddError(left.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (left as static_event_reference).en.name); - if (context.converted_type != null && context.converted_type != ((left as static_event_reference).en as common_event).cont_type && !context.converted_type.name.Contains("<>local_variables_class")) - AddError(left.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (left as static_event_reference).en.name); - } - else if (right is static_event_reference) - { - if ((right as static_event_reference).en is compiled_event) - AddError(right.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (right as static_event_reference).en.name); - if (context.converted_type != null && context.converted_type != ((right as static_event_reference).en as common_event).cont_type) - AddError(right.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (right as static_event_reference).en.name); - } - break; - } - return_value(res); - } - - private void check_property_no_params(property_node pn, location loc) - { - if (pn.parameters.Count != 0) - { - AddError(loc, "PROPERTY_{0}_REFERENCE_WITH_INVALID_PARAMS_COUNT", pn.name); - } - } - - private void check_property_params(static_property_reference pr, location loc) - { - if (pr.property.parameters.Count != pr.fact_parametres.Count) - { - AddError(loc, "PROPERTY_{0}_REFERENCE_WITH_INVALID_PARAMS_COUNT", pr.property.name); - } - } - - private void check_property_params(non_static_property_reference pr, location loc) - { - if (pr.property.parameters.Count != pr.fact_parametres.Count) - { - AddError(loc, "PROPERTY_{0}_REFERENCE_WITH_INVALID_PARAMS_COUNT", pr.property.name); - } - } - - private SyntaxTree.procedure_call ConvertEventOperationToProcedureCall(SyntaxTree.assign _assign) - { - SyntaxTree.ident event_name = _assign.to as SyntaxTree.ident; - SyntaxTree.dot_node dot = _assign.to as SyntaxTree.dot_node; - if (dot != null) - event_name = dot.right as SyntaxTree.ident; - if (event_name == null) - AddError(new EventNameExpected(get_location(_assign.to))); - string format; - if (_assign.operator_type == PascalABCCompiler.SyntaxTree.Operators.AssignmentSubtraction) - format = compiler_string_consts.event_remove_method_nameformat; - else - format = compiler_string_consts.event_add_method_nameformat; - SyntaxTree.ident add_name = new SyntaxTree.ident(string.Format(format, event_name.name)); - add_name.source_context = event_name.source_context; - if (dot != null) - dot.right = add_name; - SyntaxTree.expression_list exprlist = new SyntaxTree.expression_list(); - exprlist.expressions.Add(_assign.from); - exprlist.source_context = _assign.to.source_context; - SyntaxTree.method_call add_methcall = new SyntaxTree.method_call(exprlist); - if (dot != null) - add_methcall.dereferencing_value = dot; - else - add_methcall.dereferencing_value = add_name; - add_methcall.source_context = _assign.source_context; - SyntaxTree.procedure_call add_proccall = new SyntaxTree.procedure_call(add_methcall); - add_proccall.source_context = _assign.source_context; - return add_proccall; - } - private SyntaxTree.procedure_call ConvertOperatorToProcedureCall(SyntaxTree.assign _assign) - { - SyntaxTree.ident operator_name = new PascalABCCompiler.SyntaxTree.ident(name_reflector.get_name(_assign.operator_type)); - operator_name.source_context = _assign.to.source_context; - SyntaxTree.dot_node dot = new PascalABCCompiler.SyntaxTree.dot_node(_assign.to, operator_name); - dot.source_context = _assign.to.source_context; - SyntaxTree.expression_list exprlist = new SyntaxTree.expression_list(); - exprlist.expressions.Add(_assign.from); - exprlist.source_context = _assign.to.source_context; - SyntaxTree.method_call add_methcall = new SyntaxTree.method_call(exprlist); - add_methcall.dereferencing_value = dot; - add_methcall.source_context = _assign.source_context; - SyntaxTree.procedure_call add_proccall = new SyntaxTree.procedure_call(add_methcall); - add_proccall.source_context = _assign.source_context; - return add_proccall; - } - - private expression_node ConstructDecExpr(expression_node en, location loc) - { - int_const_node one = new int_const_node(1, loc); - return find_operator(SyntaxTree.Operators.Minus, en, one, loc); - } - - private void check_field_reference_for_assign(class_field_reference expr, location loc) - { - if (expr.obj is namespace_constant_reference || expr.obj is function_constant_reference) - AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); - else if (expr.obj is class_field_reference) check_field_reference_for_assign(expr.obj as class_field_reference,loc); - else if (expr.obj is simple_array_indexing) check_expression_for_assign((expr.obj as simple_array_indexing).simple_arr_expr,loc); - } - - private void check_expression_for_assign(expression_node expr, location loc) - { - if (expr is namespace_constant_reference || expr is function_constant_reference) - AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); - else if (expr is class_field_reference) check_field_reference_for_assign(expr as class_field_reference,loc); - else if (expr is simple_array_indexing) check_expression_for_assign((expr as simple_array_indexing).simple_arr_expr,loc); - } - - public override void visit(SyntaxTree.expression _expression) - { - throw new NotSupportedError(get_location(_expression)); - } - - public void visit_statement_list_internal(SyntaxTree.statement_list _statement_list) - { - statements_list stl = new statements_list(get_location(_statement_list), get_location_with_check(_statement_list.left_logical_bracket), get_location_with_check(_statement_list.right_logical_bracket)); - - for (var i = 0; i < _statement_list.subnodes.Count; i++) // SSM 13.10.16 - поменял т.к. собираюсь менять узлы в процессе обхода - { - statement syntax_statement = _statement_list.subnodes[i]; - try - { - statement_node semantic_statement = convert_strong(syntax_statement); - if (semantic_statement != null) - { - if (stl.statements.Count > 0 && stl.statements[0] is basic_function_call && i == 2) - { - base_function_call bfc = stl.statements[0] as basic_function_call; - if (bfc.type != null && bfc.type.name.Contains("<>local_variables_class") && (semantic_statement is compiled_constructor_call || semantic_statement is common_constructor_call) - && !context.converted_func_stack.Empty && context.converted_func_stack.top() is common_method_node && (context.converted_func_stack.top() as common_method_node).is_constructor) - stl.statements.AddElementFirst(semantic_statement); - else - stl.statements.AddElement(semantic_statement); - } - else - stl.statements.AddElement(semantic_statement); - } - context.allow_inherited_ctor_call = false; - } - catch (Errors.Error ex) - { - if (ThrowCompilationError || ex is MemberIsNotDeclaredInType || ex is UndefinedNameReference)//TODO: add interface - throw ex; - else - ErrorsList.Add(ex); - } - } - - return_value(stl); - } - - public override void visit(SyntaxTree.statement_list _statement_list) - { - if (_statement_list.IsInternal) // можно два if поставить перед push и pop здесь!!! - { - visit_statement_list_internal(_statement_list); - return; - } - - #region MikhailoMMX, обработка omp parallel section - bool isGenerateParallel = false; - bool isGenerateSequential = true; - if (OpenMP.SectionsFound) //если в программе есть хоть одна директива parallel sections - проверяем: - if (DirectivesToNodesLinks.ContainsKey(_statement_list) && OpenMP.IsParallelSectionsDirective(DirectivesToNodesLinks[_statement_list])) - { - //перед этим узлом есть директива parallel sections - if (CurrentParallelPosition == ParallelPosition.Outside) //входим в самый внешний параллельный sections - { - var f = _statement_list.DescendantNodes().OfType().FirstOrDefault(); - if (f != null) - AddError(get_location(f), "OPENMP_CONTROLLED_CONSTRUCTIONS_CANNOT_CONTAIN_LAMBDAS"); - //сгенерировать сначала последовательную ветку, затем параллельную - //устанавливаем флаг и продолжаем конвертирование, считая, что конвертируем последовательную ветку - isGenerateParallel = true; - CurrentParallelPosition = ParallelPosition.InsideSequential; - //в конце за счет флага вернем состояние обратно и сгенерируем и параллельную ветку тоже - } - else //уже генерируем одну из веток - if (CurrentParallelPosition == ParallelPosition.InsideParallel) - { - isGenerateParallel = true; - isGenerateSequential = false; - } - //else - //флаг isGenerateParallel не установлен, параллельная ветка не сгенерируется - } - #endregion - - - statements_list stl = new statements_list(get_location(_statement_list), get_location_with_check(_statement_list.left_logical_bracket), get_location_with_check(_statement_list.right_logical_bracket)); - convertion_data_and_alghoritms.statement_list_stack_push(stl); - for (var i = 0; i < _statement_list.subnodes.Count; i++) // SSM 13.10.16 - поменял т.к. собираюсь менять узлы в процессе обхода - { - statement syntax_statement = _statement_list.subnodes[i]; - try - { - statement_node semantic_statement = convert_strong(syntax_statement); - if (semantic_statement != null) - { - if (stl.statements.Count > 0 && stl.statements[0] is basic_function_call && i == 2) - { - base_function_call bfc = stl.statements[0] as basic_function_call; - if (bfc.type != null && bfc.type.name.Contains("<>local_variables_class") && - (semantic_statement is compiled_constructor_call && !(semantic_statement as compiled_constructor_call).new_obj_awaited() || semantic_statement is common_constructor_call && !(semantic_statement as common_constructor_call).new_obj_awaited()) - && !context.converted_func_stack.Empty && context.converted_func_stack.top() is common_method_node && (context.converted_func_stack.top() as common_method_node).is_constructor) - stl.statements.AddElementFirst(semantic_statement); - else - stl.statements.AddElement(semantic_statement); - } - else - stl.statements.AddElement(semantic_statement); - } - context.allow_inherited_ctor_call = false; - } - catch (Errors.Error ex) - { - if (ex is CompilationErrorWithLocation && (ex as CompilationErrorWithLocation).loc == null) - (ex as CompilationErrorWithLocation).loc = get_location(syntax_statement); - if (ThrowCompilationError || ex is MemberIsNotDeclaredInType || ex is UndefinedNameReference)//TODO: add interface - throw ex; - else - ErrorsList.Add(ex); - } - } - convertion_data_and_alghoritms.statement_list_stack.pop(); - - #region MikhailoMMX, обработка omp parallel sections - //флаг был установлен только если это самый внешний parallel sections и нужно сгенерировать обе ветки - //или если это вложенный parallel sections, нужно сгенерировать обе ветки, но без проверки на OMP_Available - //Последовательная ветка только что сгенерирована, теперь меняем состояние и генерируем параллельную - if (isGenerateParallel) - { - CurrentParallelPosition = ParallelPosition.InsideParallel; - statements_list omp_stl = OpenMP.TryConvertSections(stl, _statement_list, this); - CurrentParallelPosition = ParallelPosition.Outside; - if (omp_stl != null) - { - return_value(omp_stl); - return; - } - } - #endregion - - return_value(stl); - } - - public override void visit(SyntaxTree.syntax_tree_node _tree_node) - { - throw new NotSupportedError(get_location(_tree_node)); - } - - private bool has_dll_import_attribute(common_function_node cfn) - { - foreach (attribute_node attr in cfn.attributes) - { - if (attr.attribute_type == SystemLibrary.SystemLibrary.dllimport_type) - return true; - } - return false; - } - - private bool is_pinvoke(SyntaxTree.proc_block bl) - { - if (bl is SyntaxTree.external_directive) - { - return true; - } - return false; - } - - private attribute_node get_dll_import_attribute(common_function_node cfn) - { - foreach (attribute_node attr in cfn.attributes) - { - if (attr.attribute_type == SystemLibrary.SystemLibrary.dllimport_type) - return attr; - } - return null; - } - - public override void visit(SyntaxTree.external_directive _external_directive) - { - string module_name = ""; - string name = ""; - if (context.converted_func_stack.size > 1) - AddError(context.top_function.loc, "EXTERNAL_METHOD_CANNOT_BE_NESTED"); - if (context.converted_func_stack.top() is common_method_node && (context.converted_func_stack.top() as common_method_node).polymorphic_state != SemanticTree.polymorphic_state.ps_static) - AddError(context.top_function.loc, "EXTERNAL_METHOD_SHOULD_BE_STATIC"); - if (context.converted_func_stack.top().is_generic_function) - AddError(context.top_function.loc, "EXTERNAL_METHOD_CANNOT_BE_GENERIC"); - if (context.converted_func_stack.top() is common_method_node && (context.converted_func_stack.top() as common_method_node).common_comprehensive_type.is_generic_type_definition) - AddError(context.top_function.loc, "EXTERNAL_METHOD_CANNOT_BE_DECLARED_IN_GENERIC_TYPE"); - - if (_external_directive.modulename == null) - { - if (!has_dll_import_attribute(context.top_function)) - { - AddError(context.top_function.loc, "FUNCTION_MUST_HAVE_DLLIMPORT_ATTRIBUTE"); - } - else - { - location loc2 = get_location(_external_directive); - pinvoke_statement pinv_stmt = new pinvoke_statement(loc2); - //statement_node_list sal = new statement_node_list(loc); - //sal.AddElement(ext_stmt); - statements_list sl2 = new statements_list(loc2); - sl2.statements.AddElement(pinv_stmt); - //return_value(sl); - context.code = sl2; - return; - } - } - if (has_dll_import_attribute(context.top_function)) - { - AddError(get_location(_external_directive.modulename), "FUNCTION_MUST_HAVE_ONLY_EXTERNAL_STATEMENT"); - } - if (_external_directive.modulename is SyntaxTree.string_const) - { - module_name = ((SyntaxTree.string_const)_external_directive.modulename).Value; - } - else if (_external_directive.modulename is SyntaxTree.ident) - { - //throw new CompilerInternalError("Unsupported now"); - //throw new NotSupportedError(get_location(_external_directive)); - expression_node en = convert_strong(_external_directive.modulename as SyntaxTree.ident); - if (en is string_const_node) - module_name = (en as string_const_node).constant_value; - else - AddError(get_location(_external_directive.modulename), "STRING_CONSTANT_EXPECTED"); - } - else - AddError(get_location(_external_directive.modulename), "STRING_CONSTANT_OR_IDENTIFIER_EXPECTED"); - if (_external_directive.name == null) - { - name = context.converted_func_stack.top().name; - } - else - if (_external_directive.name is SyntaxTree.string_const) - { - name = ((SyntaxTree.string_const)_external_directive.name).Value; - } - else if (_external_directive.name is SyntaxTree.ident) - { - expression_node en = convert_strong(_external_directive.name as SyntaxTree.ident); - if (en is string_const_node) - name = (en as string_const_node).constant_value; - else - AddError(get_location(_external_directive.name), "STRING_CONSTANT_EXPECTED"); - } - else - { - //throw new CompilerInternalError("Unsupported now"); - AddError(get_location(_external_directive.name), "STRING_CONSTANT_OR_IDENTIFIER_EXPECTED"); - } - location loc = get_location(_external_directive); - external_statement ext_stmt = new external_statement(module_name, name, loc); - //statement_node_list sal = new statement_node_list(loc); - //sal.AddElement(ext_stmt); - statements_list sl = new statements_list(loc); - sl.statements.AddElement(ext_stmt); - //return_value(sl); - context.code = sl; - } - - public override void visit(SyntaxTree.unit_or_namespace _name_space) - { - throw new NotSupportedError(get_location(_name_space)); - } - - public override void visit(SyntaxTree.using_list _using_list) - { - throw new NotSupportedError(get_location(_using_list)); - } - - public override void visit(SyntaxTree.jump_stmt _return_stmt) - { - if (_return_stmt.JumpType != PascalABCCompiler.SyntaxTree.JumpStmtType.Return) - { - throw new NotSupportedError(get_location(_return_stmt)); - } - if (_return_stmt.expr == null) - { - if (context.top_function.return_value_type != null && context.top_function.return_value_type != SystemLibrary.SystemLibrary.void_type) - { - AddError(get_location(_return_stmt), "FUNCTION_SHOULD_RETURN_VALUE"); - ret.return_value(new empty_statement(null)); - return; - } - ret.return_value(new return_node(null, null)); - } - else - { - type_node rettype = context.top_function.return_value_type; - if (rettype == null || rettype == SystemLibrary.SystemLibrary.void_type) - { - AddError(get_location(_return_stmt.expr), "FUNCTION_SHOULD_NOT_RETURN_VALUE"); - ret.return_value(new empty_statement(null)); - return; - } - expression_node en = convert_strong(_return_stmt.expr); - en = convertion_data_and_alghoritms.convert_type(en, rettype); - ret.return_value(new return_node(en, get_location(_return_stmt.expr))); - } - } - - public override void visit(SyntaxTree.loop_stmt _loop_stmt) - { - throw new NotSupportedError(get_location(_loop_stmt)); - } - - private bool IsGetEnumerator(type_node tn, ref type_node elem_type) - { - if (tn == null || tn is null_type_node || tn.ImplementingInterfaces == null) return false; - compiled_type_node ctn = compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IEnumerableInterfaceName)); - if (tn == ctn) - return true; - foreach (SemanticTree.ITypeNode itn in tn.ImplementingInterfaces) - { - if (itn == ctn) - { - elem_type = tn.element_type; - if (elem_type != null) return true; - function_node get_enumerator_func = null; - List sil = ctn.find_in_type(compiler_string_consts.GetEnumeratorMethodName); - if(sil != null) - foreach(SymbolInfo si in sil) - { - if (get_enumerator_func != null) - break; - get_enumerator_func = si.sym_info as function_node; - if (get_enumerator_func.parameters.Count == 0) - break; - get_enumerator_func = null; - } - elem_type = (get_enumerator_func.return_value_type.find_first_in_type(compiler_string_consts.CurrentPropertyName).sym_info as property_node).get_function.return_value_type; - return true; - } - } - return false; - } - - public bool FindIEnumerableElementType(type_node tn, ref type_node elem_type, out bool sys_coll_ienum) - { - sys_coll_ienum = false; - var IEnstring = "System.Collections.IEnumerable"; - compiled_type_node ctn = compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(IEnstring)); - if (tn is compiled_type_node || tn is compiled_generic_instance_type_node) // Если этот тип зашит в .NET - // IEnumerable, Range(1,10), Dictionary: tn = compiled_type_node - // IEnumerable: tn = compiled_generic_instance_type_node - // FibGen = class(IEnumerable,IEnumerator): tn = common_type_node, en = compiled_type_node - // array of Person: tn = common_type_node - { - compiled_type_node orig; - - if (tn is compiled_type_node) - orig = tn as compiled_type_node; - else orig = (tn as compiled_generic_instance_type_node).original_generic as compiled_type_node; - //var pars = tn.instance_params; - System.Type ct = orig.compiled_type; - - Type r; - var IEnTstring = "System.Collections.Generic.IEnumerable`1"; - //if (ct.ToString().StartsWith(IEnTstring)) // SSM Ошибка!!! IEnumerable`1[] тоже начинается с IEnumerable`1, но это массив! - if (ct.Name.Equals("IEnumerable`1")) - r = ct; - else - r = ct.GetInterface(IEnTstring); - if (r != null) - { - Type arg1 = r.GetGenericArguments().First(); // тип параметра IEnumerable - var str = arg1.GetGenericArguments().Count(); - if (tn is compiled_type_node) - { - elem_type = compiled_type_node.get_type_node(arg1); - } - else - { - if (arg1.GetGenericArguments().Count()>0) - { - elem_type = compiled_type_node.get_type_node(arg1.GetGenericTypeDefinition()); - elem_type = elem_type.get_instance(tn.instance_params); // SSM 19/07/15 - работает!!! - } - else - { - var ip = tn.instance_params; - - var IGrTstring = "System.Linq.IGrouping`2"; - if (ct.ToString().StartsWith(IGrTstring)) - elem_type = ip[1]; - else - { - var ln = tn.ImplementingInterfaces; - elem_type = null; - foreach (var x in ln) - { - var xctn = x as compiled_generic_instance_type_node; - if (xctn != null && xctn.name.StartsWith("IEnumerable<")) // Немного грубовато. - { - elem_type = xctn.instance_params[0]; - break; - } - } - if (elem_type == null) - elem_type = ip[0]; - } - - //var Tname = ip[0].name; - //elem_type = convert_strong(new SyntaxTree.named_type_reference(Tname, _foreach_stmt.in_what.source_context)); - } - - //elem_type.instance_params = tn.instance_params; - //var ip = tn.instance_params; - //var Tname = new string(tn.name.SkipWhile(c => c != '<').Skip(1).TakeWhile(c => c != ',' && c != '>').ToArray()); - //var Tname = ip[0].name; - //var Tname = "System.Collections.Generic.KeyValuePair'2"; // - //elem_type = convert_strong(new SyntaxTree.named_type_reference(Tname, _foreach_stmt.in_what.source_context)); - } - return true; - } - else - { - if (tn.element_type != null) // значит, это массив любой размерности - 02.02.16 SSM - еще может быть множество set of T - 22.02.16 SSM - { - elem_type = tn.element_type; - return true; - } - - var ttt = tn.ImplementingInterfaces; - foreach (SemanticTree.ITypeNode itn in tn.ImplementingInterfaces) - { - if (itn == ctn) - { - elem_type = SystemLibrary.SystemLibrary.object_type; - sys_coll_ienum = true; - return true; - } - } - } - } - /*else if (tn is compiled_generic_instance_type_node) - { - var g = tn as compiled_generic_instance_type_node; - var og = g.original_generic; - var tt = og.ImplementingInterfaces; - if (_foreach_stmt.type_name != null && _foreach_stmt.type_name.GetType()!=typeof(SyntaxTree.no_type_foreach)) - elem_type = convert_strong(_foreach_stmt.type_name); - else - { - var fn = tn.full_name; - } - return true; - } */ - else // если мы самостоятельно определяем этот тип - можно реализовать в PascalABC.NET только IEnumerable. // Сейчас уже можно!!!!! - // Попытка реализовать IEnumerable натыкается на необходимость определять GetEnumerator, возвращающий IEnumerator и IEnumerator - { - if (tn == null || tn is null_type_node || tn.ImplementingInterfaces == null) - { - if (tn != null && tn.base_type != null) - return FindIEnumerableElementType(tn.base_type, ref elem_type, out sys_coll_ienum); - return false; - } - - if (tn.element_type != null && tn.type_special_kind != SemanticTree.type_special_kind.typed_file) // еще может быть множество set of T - 22.02.16 SSM - { - elem_type = tn.element_type; - return true; - } - - foreach (SemanticTree.ITypeNode itn in tn.ImplementingInterfaces) // Ищем интерфейс IEnumerable и возвращаем T в качестве elem_type - { - if (itn is compiled_generic_instance_type_node) - { - var itnc = (itn as compiled_generic_instance_type_node); - var tt = (itnc.original_generic as compiled_type_node).compiled_type; - if (tt == typeof(System.Collections.Generic.IEnumerable<>)) - { - elem_type = itnc.generic_parameters[0] as common_type_node; - return true; - } - } - } - - foreach (SemanticTree.ITypeNode itn in tn.ImplementingInterfaces) // если не нашли - ищем интерфейс IEnumerable и возвращаем object в качестве elem_type - { - if (itn is compiled_type_node) // Именно этот кусок отвечает за IEnumerable и мы его закомментировали - { - var itnc = (itn as compiled_type_node).compiled_type; /* SSM раскомментировал 15.05.2020 - пришла пора*/ - if (itnc.IsGenericType) - { - var my = itnc.GetGenericTypeDefinition();// = typeof(System.Collections.Generic.IEnumerable<>) - if (my == typeof(System.Collections.Generic.IEnumerable<>)) - { - var aarg1 = itnc.GetGenericArguments().First(); - elem_type = compiled_type_node.get_type_node(aarg1); - return true; - } - } - else /* end SSM раскомментировал 15.05.2020 - пришла пора*/ - if (itn == ctn) - { - elem_type = SystemLibrary.SystemLibrary.object_type; - sys_coll_ienum = true; - return true; - } - } - } - } - if (tn != null && tn.base_type != null) - return FindIEnumerableElementType(tn.base_type, ref elem_type, out sys_coll_ienum); - return false; - } - - private int GenIdNum = 0; - public ident GenIdentName() - { - GenIdNum++; - return new ident("$GenId" + GenIdNum.ToString()); - } - - public override void visit(SyntaxTree.addressed_value_funcname _addressed_value_funcname) - { - throw new NotSupportedError(get_location(_addressed_value_funcname)); - } - - public override void visit(SyntaxTree.named_type_reference_list _named_type_reference_list) - { - throw new NotSupportedError(get_location(_named_type_reference_list)); - } - - public override void visit(SyntaxTree.template_param_list _template_param_list) - { - throw new NotSupportedError(get_location(_template_param_list)); - } - - public override void visit(double_question_node node) - { - expression_node condition = convert_strong(node.left); - - convertion_data_and_alghoritms.convert_type(new null_const_node(null_type_node.get_type_node(), condition.location), condition.type); - expression_node left = condition; - expression_node right = convert_strong(node.right); - if (condition is null_const_node) - convertion_data_and_alghoritms.convert_type(new null_const_node(null_type_node.get_type_node(), right.location), right.type); - - try_convert_typed_expression_to_function_call(ref left); - try_convert_typed_expression_to_function_call(ref right); - - if (left is null_const_node && right.type.is_value_type) - { - if (right.type is compiled_type_node) - { - var rt = right.type as compiled_type_node; - if (!rt.compiled_type.IsGenericType || rt.compiled_type.GetGenericTypeDefinition() != typeof(System.Nullable<>)) - { - right = convert_strong(ToNullable(node.right)); - } - } - } - else - if (right is null_const_node && left.type.is_value_type) - { - if (left.type is compiled_type_node) - { - var lt = left.type as compiled_type_node; - if (!lt.compiled_type.IsGenericType || lt.compiled_type.GetGenericTypeDefinition() != typeof(System.Nullable<>)) - { - left = convert_strong(ToNullable(node.left)); - } - } - } - - /*var typeComparisonResult = type_table.compare_types(left.type, right.type); - if (typeComparisonResult == type_compare.greater_type) - right = convertion_data_and_alghoritms.convert_type(right, left.type); - else left = convertion_data_and_alghoritms.convert_type(left, right.type);*/ - if (left is null_const_node) - { - left = convertion_data_and_alghoritms.convert_type(left, right.type); - } - else - { - delegated_methods del_left = left.type as delegated_methods; - delegated_methods del_right = right.type as delegated_methods; - if (del_left != null && del_right != null && del_left.empty_param_method == null && del_right.empty_param_method == null) - { - base_function_call bfc = del_left.proper_methods[0]; - common_type_node del = - convertion_data_and_alghoritms.type_constructor.create_delegate(context.get_delegate_type_name(), bfc.simple_function_node.return_value_type, bfc.simple_function_node.parameters, context.converted_namespace, null); - context.converted_namespace.types.AddElement(del); - right = convertion_data_and_alghoritms.explicit_convert_type(right, del); - left = convertion_data_and_alghoritms.explicit_convert_type(left, del); - } - else - { - var rtl = type_table.get_convertions(right.type, left.type); - var ltr = type_table.get_convertions(left.type, right.type); - - if (ltr.first != null && rtl.first == null) - { - left = convertion_data_and_alghoritms.convert_type(left, right.type); - } - else if (ltr.first == null && rtl.first != null) - { - right = convertion_data_and_alghoritms.convert_type(right, left.type); - } - else - { - // если оба типа - целые - if (convertion_data_and_alghoritms.is_value_int_type(left.type) && convertion_data_and_alghoritms.is_value_int_type(right.type)) - { - var lub = convertion_data_and_alghoritms.least_upper_bound_value_int_type(left.type, right.type); - if (lub == left.type) - right = convertion_data_and_alghoritms.convert_type(right, left.type); - else if (lub == right.type) - left = convertion_data_and_alghoritms.convert_type(left, right.type); - else - { - right = convertion_data_and_alghoritms.convert_type(right, lub); - left = convertion_data_and_alghoritms.convert_type(right, lub); - } - } - else if (left.type == SystemLibrary.SystemLibrary.float_type && right.type == SystemLibrary.SystemLibrary.double_type) - left = convertion_data_and_alghoritms.convert_type(left, right.type); - else if (right.type == SystemLibrary.SystemLibrary.float_type && left.type == SystemLibrary.SystemLibrary.double_type) - right = convertion_data_and_alghoritms.convert_type(right, left.type); - else if (left.type == right.type) - { } - else // Это было - для совместимости. Что-то может не учтено - { - right = convertion_data_and_alghoritms.convert_type(right, left.type); - } - - } - - } - - } - - - //right = convertion_data_and_alghoritms.convert_type(right, left.type); - return_value(new double_question_colon_expression(condition, right, get_location(node))); - } - - public override void visit(SyntaxTree.question_colon_expression node) - { - expression_node condition = convert_strong(node.condition); - condition = convertion_data_and_alghoritms.convert_type(condition, SystemLibrary.SystemLibrary.bool_type); - expression_node left = convert_strong(node.ret_if_true); - expression_node right = convert_strong(node.ret_if_false); - - try_convert_typed_expression_to_function_call(ref left); - try_convert_typed_expression_to_function_call(ref right); - - if (left is null_const_node && right.type.is_value_type) - { - if (right.type is compiled_type_node) - { - var rt = right.type as compiled_type_node; - if (!rt.compiled_type.IsGenericType || rt.compiled_type.GetGenericTypeDefinition() != typeof(System.Nullable<>)) - { - right = convert_strong(ToNullable(node.ret_if_false)); - } - } - } - else - if (right is null_const_node && left.type.is_value_type) - { - if (left.type is compiled_type_node) - { - var lt = left.type as compiled_type_node; - if (!lt.compiled_type.IsGenericType || lt.compiled_type.GetGenericTypeDefinition() != typeof(System.Nullable<>)) - { - left = convert_strong(ToNullable(node.ret_if_true)); - } - } - } - - /*var typeComparisonResult = type_table.compare_types(left.type, right.type); - if (typeComparisonResult == type_compare.greater_type) - right = convertion_data_and_alghoritms.convert_type(right, left.type); - else left = convertion_data_and_alghoritms.convert_type(left, right.type);*/ - if (left is null_const_node) - { - left = convertion_data_and_alghoritms.convert_type(left, right.type); - } - else - { - delegated_methods del_left = left.type as delegated_methods; - delegated_methods del_right = right.type as delegated_methods; - if (del_left != null && del_right != null && del_left.empty_param_method == null && del_right.empty_param_method == null) - { - base_function_call bfc = del_left.proper_methods[0]; - common_type_node del = - convertion_data_and_alghoritms.type_constructor.create_delegate(context.get_delegate_type_name(), bfc.simple_function_node.return_value_type, bfc.simple_function_node.parameters, context.converted_namespace, null); - context.converted_namespace.types.AddElement(del); - right = convertion_data_and_alghoritms.explicit_convert_type(right, del); - left = convertion_data_and_alghoritms.explicit_convert_type(left, del); - } - else - { - var rtl = type_table.get_convertions(right.type, left.type); - var ltr = type_table.get_convertions(left.type, right.type); - - if (ltr.first != null && rtl.first == null) - { - left = convertion_data_and_alghoritms.convert_type(left, right.type); - } - else if (ltr.first == null && rtl.first != null) - { - right = convertion_data_and_alghoritms.convert_type(right, left.type); - } - else - { - // если оба типа - целые - if (convertion_data_and_alghoritms.is_value_int_type(left.type) && convertion_data_and_alghoritms.is_value_int_type(right.type)) - { - var lub = convertion_data_and_alghoritms.least_upper_bound_value_int_type(left.type, right.type); - if (lub == left.type) - right = convertion_data_and_alghoritms.convert_type(right, left.type); - else if (lub == right.type) - left = convertion_data_and_alghoritms.convert_type(left, right.type); - else - { - right = convertion_data_and_alghoritms.convert_type(right, lub); - left = convertion_data_and_alghoritms.convert_type(right, lub); - } - } - else if (left.type == SystemLibrary.SystemLibrary.float_type && right.type == SystemLibrary.SystemLibrary.double_type) - left = convertion_data_and_alghoritms.convert_type(left, right.type); - else if (right.type == SystemLibrary.SystemLibrary.float_type && left.type == SystemLibrary.SystemLibrary.double_type) - right = convertion_data_and_alghoritms.convert_type(right, left.type); - else if (left.type == right.type) - { } - else // Это было - для совместимости. Что-то может не учтено - { - right = convertion_data_and_alghoritms.convert_type(right, left.type); - } - - } - - } - - } - - - //right = convertion_data_and_alghoritms.convert_type(right, left.type); - return_value(new question_colon_expression(condition, left, right, get_location(node))); - } - - Dictionary delegate_cache = new Dictionary(); - - public List visit_type_list(List types) - { - List tparams = new List(); - foreach (SyntaxTree.type_definition id in types) - { - type_node tn = null; - if ((id is function_header || id is procedure_header) && delegate_cache.ContainsKey(id)) - tn = delegate_cache[id]; - else - tn = convert_strong(id); - - if (tn == null) - { - AddError(get_location(id), "TYPE_NAME_EXPECTED"); - } - if ((id is function_header || id is procedure_header) && !delegate_cache.ContainsKey(id)) - { - delegate_cache[id] = tn; - } - tparams.Add(tn); - } - return tparams; - } - - public List visit_type_list_with_check(List types, List gpe_list, bool where_checking) - { - List tparams = new List(); - foreach (SyntaxTree.type_definition id in types) - { - type_node tn = convert_strong(id); - CompilationErrorWithLocation not_useful = generic_parameter_eliminations.check_type_generic_useful(tn, get_location(id)); - if (not_useful != null) - { - AddError(not_useful); - } - tparams.Add(tn); - } - //Проверяем типы на соответствие ограничениям - int i; - if (where_checking) - { - CompilationErrorWithLocation err = generic_parameter_eliminations.check_type_list(tparams, gpe_list, false, out i); - if (err != null) - { - err.loc = get_location(types[i]); - AddError(err); - } - } - return tparams; - } - - public type_node get_generic_instance(SymbolInfo si, List type_pars) - { - type_node node = si.sym_info as type_node; - compiled_type_node comp_node = node as compiled_type_node; - List lgpe = null; - if (!context.skip_check_where_sections) - { - lgpe = (comp_node == null) ? - (node as common_type_node).parameters_eliminations : - comp_node.parameters_eliminations; - } - List tparams = visit_type_list_with_check(type_pars, lgpe, !context.skip_check_where_sections); - return node.get_instance(tparams); - } - - public SymbolInfo ConvertTypeToInstance(SymbolInfo si, List type_pars, location loc) - { - if (si == null) - return null; - template_class tclass = si.sym_info as template_class; - if (tclass == null) - { - generic_indicator gi = si.sym_info as generic_indicator; - if (gi != null) - { - AddError(loc, "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", gi.generic.name, gi.generic.generic_params.Count); - } - return null; - } - //Формируем список параметров инстанцирования - List tparams = visit_type_list(type_pars); - - type_node t = instance_any(tclass, tparams, loc); - return new SymbolInfo(t); - } - - public override void visit(SyntaxTree.template_type_reference _template_type_reference) - { - int last_num = _template_type_reference.name.names.Count; - string typename = _template_type_reference.name.names[last_num - 1].name; - location loc = get_location(_template_type_reference); - List sil; - List tparams; - - //Обрабатываем generic-типы - int tcount = _template_type_reference.params_list.params_list.Count; - string temp_name = _template_type_reference.name.names[last_num - 1].name; - if (!_template_type_reference.name.names[last_num - 1].name.Contains(compiler_string_consts.generic_params_infix)) // SSM 26.03.14 - _template_type_reference.name.names[last_num - 1].name += compiler_string_consts.generic_params_infix + tcount; - sil = context.find_definition_node(_template_type_reference.name, loc); - if (sil != null) - { - type_node rez_type = sil?.FirstOrDefault().sym_info as type_node; - foreach (type_definition td in _template_type_reference.params_list.params_list) - if (td is named_type_reference && (td as named_type_reference).names.Count > 0 && (td as named_type_reference).names[0].name == "") - { - return_value(rez_type); - return; - } - rez_type = get_generic_instance(sil?.FirstOrDefault(), _template_type_reference.params_list.params_list); - if (context.skip_check_where_sections) - { - generic_instance_type_node gitn = rez_type as generic_instance_type_node; - if (gitn != null) - { - context.possible_incorrect_instances.Add( - new type_instance_and_location(gitn, loc)); - } - } - return_value(rez_type); - return; - } - _template_type_reference.name.names[last_num - 1].name = temp_name; - sil = context.find_definition_node(_template_type_reference.name, loc); - if (sil == null) - { - check_possible_generic_names(_template_type_reference.name, loc); - AddError(new UndefinedNameReference(typename, loc)); - } - template_class tclass = sil.FirstOrDefault().sym_info as template_class; - if (tclass == null) - { - generic_indicator gi = sil.FirstOrDefault().sym_info as generic_indicator; - if (gi != null) - { - AddError(get_location(_template_type_reference), "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", typename, gi.generic.generic_params.Count); - } - AddError(get_location(_template_type_reference), "{0}_IS_NOT_TEMPLATE_CLASS", typename); - } - foreach (type_definition td in _template_type_reference.params_list.params_list) - if (td is named_type_reference && (td as named_type_reference).names.Count > 0 && (td as named_type_reference).names[0].name == "") - { - if (tclass.type_dec.type_def is template_type_reference) - { - template_type_reference ttr = new template_type_reference((tclass.type_dec.type_def as template_type_reference).name, _template_type_reference.params_list, _template_type_reference.source_context); - ttr.names = (tclass.type_dec.type_def as template_type_reference).names; - if (ttr.name.names.Count >= 1 && ttr.name.names[ttr.name.names.Count - 1].name.IndexOf('`') != -1) - ttr.name.names[ttr.name.names.Count - 1].name = ttr.name.names[ttr.name.names.Count - 1].name.Substring(0, ttr.name.names[ttr.name.names.Count - 1].name.IndexOf('`')); - - return_value(convert_strong(ttr)); - return; - } - else if (tclass.type_dec.type_def is named_type_reference) - { - return_value(convert_strong(tclass.type_dec.type_def)); - return; - } - } - //Формируем список параметров инстанцирования - tparams = visit_type_list(_template_type_reference.params_list.params_list); - - type_node t = instance_any(tclass, tparams, get_location(_template_type_reference), _template_type_reference); - return_value(t); - } - - public type_node instance_any(template_class tc, List template_params, location loc, template_type_reference ttr=null) - { - common_type_node t = instance(tc, template_params, loc, ttr); - if (tc.is_synonym) - { - return t.fields[0].type; - } - return t; - } - - public common_type_node instance(template_class tc, List template_params, location loc, template_type_reference used_ttr = null) - { - //Проверяем, что попытка инстанцирования корректна - SyntaxTree.class_definition cl_def = tc.type_dec.type_def as SyntaxTree.class_definition; - SyntaxTree.template_type_name ttn = tc.type_dec.type_name as SyntaxTree.template_type_name; -#if (DEBUG) - if (!tc.is_synonym) - { - if (cl_def == null) - { - throw new PascalABCCompiler.TreeConverter.CompilerInternalError("No body definition in template class."); - } - if (cl_def.template_args == null || cl_def.template_args.idents == null) - { - throw new PascalABCCompiler.TreeConverter.CompilerInternalError("No template arguments in syntax tree."); - } - } - else - { - if (ttn == null) - { - throw new PascalABCCompiler.TreeConverter.CompilerInternalError("No template name."); - } - } -#endif - List template_formals = (tc.is_synonym) ? - ttn.template_args.idents : cl_def.template_args.idents; - if (template_formals.Count != ttn.template_args.idents.Count) - { - AddError(loc, "TEMPLATE_ARGUMENTS_COUNT_MISMATCH"); - } - - if (!tc.is_synonym) - { - foreach (type_node tnode in template_params) - { - if (depended_from_generic_parameter(tnode)) - { - AddError(loc, "TEMPLATES_AND_GENERICS_ARE_INCOMPATIBLE"); - } - } - } - - //А вдруг такая инстанция уже есть - вернём её - string inst_name = tc.CreateTemplateInstance(template_params, loc); - List sil = tc.cnn.scope.FindOnlyInScope(inst_name); - if (sil != null) - { - return (common_type_node)sil.FirstOrDefault().sym_info; - } - - //Переходим в место описания шаблона - common_namespace_node current_namespace = context.converted_namespace; - context.converted_namespace = tc.cnn; - common_type_node current_type = context.converted_type; - context.converted_type = null; - template_class current_template = context.converted_template_type; - context.converted_template_type = null; - compiled_type_node current_compiled_type = context.converted_compiled_type; - context.converted_compiled_type = null; - common_function_node_stack current_funk_stack = context.converted_func_stack; - context.converted_func_stack = new common_function_node_stack(); //Думаю, это будет работать - - //DarkStar - statement_list_stack statement_list_stack = convertion_data_and_alghoritms.statement_list_stack; - convertion_data_and_alghoritms.statement_list_stack = new statement_list_stack(); - - bool current_cur_meth_not_in_class = current_converted_method_not_in_class_defined; - current_converted_method_not_in_class_defined = false; - SymbolInfo current_last_created_function = context.last_created_function; - context.last_created_function = null; - bool current_record_created = _record_created; - _record_created = false; - SemanticTree.field_access_level current_fal = context.get_field_access_level(); - document current_doc = current_document; - current_document = tc.cur_document; - bool current_body_exists = body_exists; - body_exists = false; - bool current_allow_inherited_ctor_call = context.allow_inherited_ctor_call; - bool current_is_direct_type_decl = is_direct_type_decl; - is_direct_type_decl = false; - context.allow_inherited_ctor_call = false; - bool current_type_section_converting = type_section_converting; - type_section_converting = true; - SemanticTree.field_access_level curr_fal = context.get_field_access_level(); - List current_var_defs = context.var_defs; - context.var_defs = new List(); - Hashtable current_member_decls = context.member_decls; - context.member_decls = new Hashtable(); - //подменяем using-список - using_namespace_list current_using_list = new using_namespace_list(); - foreach (using_namespace un in using_list) - { - current_using_list.AddElement(un); - } - using_list.clear(); - foreach (using_namespace un in tc.using_list) - { - using_list.AddElement(un); - } - context.converted_type = null; - context.enter_code_block_without_bind(); - - common_type_node ctn; - - bool interface_creating = false; - - //Создаём инстанцию шаблона - if (tc.is_synonym) - { - ctn = context.create_type(inst_name, get_location(ttn)); - } - else - { - if (cl_def.keyword == SyntaxTree.class_keyword.Record) - { - ctn = context.create_record_type(get_location(tc.type_dec.type_name), inst_name); - } - else - { - interface_creating = (cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.Interface); - ctn = context.advanced_create_type(inst_name, get_location(tc.type_dec.type_name), interface_creating); - } - } - ctn.original_template = tc; - bool indefinite = false; - foreach (type_node tn in template_params) - { - indefinite = indefinite || tn.depended_from_indefinite; - } - ctn.SetDependedFromIndefinite(indefinite); - tc.instance_params.Add(ctn, template_params); - - //Ставим в соответствие формальным параметрам шаблона фактические - for (int i = 0; i < template_params.Count; i++) - { - ctn.Scope.AddSymbol(template_formals[i].name, new SymbolInfo(template_params[i])); - } - - //Разбор тела класса - if (tc.is_synonym) - { - Dictionary saved_sc_dict = new Dictionary(); - saved_sc_dict.Add(tc.type_dec.type_def, tc.type_dec.type_def.source_context); - tc.type_dec.type_def.source_context = loc; - - if (tc.type_dec.type_def is template_type_reference) - { - template_type_reference ttr = tc.type_dec.type_def as template_type_reference; - for (int i = 0; i < ttr.params_list.params_list.Count; i++) - { - var prm = ttr.params_list.params_list[i]; - saved_sc_dict.Add(prm, prm.source_context); - if (used_ttr != null && i < used_ttr.params_list.params_list.Count) - prm.source_context = used_ttr.params_list.params_list[i].source_context; - else - prm.source_context = loc; - } - } - type_node synonym_value = convert_strong(tc.type_dec.type_def); - foreach (type_definition td in saved_sc_dict.Keys) - td.source_context = saved_sc_dict[td]; - ctn.fields.AddElement(new class_field(compiler_string_consts.synonym_value_name, - synonym_value, ctn, PascalABCCompiler.SemanticTree.polymorphic_state.ps_static, - PascalABCCompiler.SemanticTree.field_access_level.fal_public, null)); - } - else - { - if (cl_def.keyword == SyntaxTree.class_keyword.Record) - { - _record_created = true; - } - - bool tmp_direct = is_direct_type_decl; - is_direct_type_decl = true; - hard_node_test_and_visit(cl_def); - is_direct_type_decl = tmp_direct; - - //Разбор методов, описанных вне класса - if (!interface_creating) - { - type_section_converting = false; - foreach (procedure_definition_info pdi in tc.external_methods) - { - if (context.converted_namespace != pdi.nspace) - { - context.converted_namespace = pdi.nspace; - using_namespace_list ulist = - (pdi.nspace == tc.cnn) ? tc.using_list : tc.using_list2; - using_list.clear(); - foreach (using_namespace un in ulist) - { - using_list.AddElement(un); - } - template_class.AddUsingListToScope(context.converted_namespace.scope, ulist); - } - - //Заменяем в дереве метода имя шаблонного класса на имя инстанции - string tmp_name = pdi.proc.proc_header.name.class_name.name; - pdi.proc.proc_header.name.class_name.name = inst_name; - - hard_node_test_and_visit(pdi.proc); - - //Обратная замена - pdi.proc.proc_header.name.class_name.name = tmp_name; - } - - foreach (common_method_node cmn in ctn.methods) - { - if (cmn.function_code == null) - { - //AddError(cmn.loc, "FUNCTION_PREDEFINITION_WITHOUT_DEFINITION"); - AddError(new FunctionPredefinitionWithoutDefinition(cmn, cmn.loc)); - } - } - } - } - - //Прыжок обратно - context.leave_code_block(); - context.converted_namespace = current_namespace; - context.converted_type = current_type; - context.converted_template_type = current_template; - context.set_field_access_level(current_fal); - context.converted_func_stack = current_funk_stack; - context.converted_compiled_type = current_compiled_type; - convertion_data_and_alghoritms.statement_list_stack = statement_list_stack; - current_document = current_doc; - body_exists = current_body_exists; - _record_created = current_record_created; - context.last_created_function = current_last_created_function; - is_direct_type_decl = current_is_direct_type_decl; - context.allow_inherited_ctor_call = current_allow_inherited_ctor_call; - current_converted_method_not_in_class_defined = current_cur_meth_not_in_class; - context.set_field_access_level(curr_fal); - type_section_converting = current_type_section_converting; - context.member_decls = current_member_decls; - context.var_defs = current_var_defs; - using_list.clear(); - foreach (using_namespace un in current_using_list) - { - using_list.AddElement(un); - } - - return ctn; - } - - private SyntaxTree.addressed_value convert_named_type_reference_to_addressed_value(SyntaxTree.named_type_reference ntr) - { - SyntaxTree.addressed_value adrv = ntr.names[0]; - for (int i = 1; i < ntr.names.Count; i++) - adrv = new SyntaxTree.dot_node(adrv, ntr.names[i]); - return adrv; - } - - private base_function_call create_constructor_call(type_node tn, expressions_list exprs, location loc, Tuple> lambdas_info = null) - { - if (tn.IsInterface) - { - AddError(loc, "INTERFACE_{0}_CONSTRUCTOR_CALL", tn.name); - } - if (tn.IsStatic) - { - AddError(loc, "STATIC_CONSTRUCTOR_CALL"); - } - if (tn.IsAbstract) - { - AddError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", tn.name); - } - List sil = tn.find_in_type(TreeConverter.compiler_string_consts.default_constructor_name, context.CurrentScope); //tn.Scope); - delete_inherited_constructors(ref sil, tn); - if (sil == null) - AddError(loc, "CONSTRUCTOR_NOT_FOUND"); - function_node fnn = null; - try - { - #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим - //lroman// - if (lambdas_info != null && lambdas_info.Item1) - { - LambdaHelper.processingLambdaParametersForTypeInference++; - var syntax_nodes_parameters = lambdas_info.Item2; - - // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями - List spf = null; - try - { - function_node fn = convertion_data_and_alghoritms.select_function(exprs, sil, loc, - syntax_nodes_parameters); - int exprCounter = 0; - foreach (SyntaxTree.expression en in syntax_nodes_parameters) - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - exprCounter++; - continue; - } - else - { - var enLambda = (SyntaxTree.function_lambda_definition)en; - LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type, enLambda, this); - enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; - exprs[exprCounter] = convert_strong(en); - enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; - exprCounter++; - } - } - } - catch (SeveralFunctionsCanBeCalled sf) - { - spf = sf.set_of_possible_functions; - // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна - } - - Exception lastmultex = null; - if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try - { - // exprs - глобальная, поэтому надо копировать - int spfnum = -1; // spfnum - первый номер правильно инстанцированной. Пока -1. Если потом встретился второй, то тоже ошибка - int GoodVersionsCount = 0; - int GoodVersionsCountWithSameResType = 0; - for (int i = 0; i < spf.Count; i++) - { - function_node fn = spf[i]; - try - { - int exprCounter = 0; - expressions_list exprs1 = new expressions_list(); - exprs1.AddRange(exprs); // сделали копию - - foreach (SyntaxTree.expression en in syntax_nodes_parameters) - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - exprCounter++; - continue; - } - else - { - var fld = en as SyntaxTree.function_lambda_definition; - - var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо - var fl = fld.lambda_visit_mode; - - // запомнили типы параметров лямбды - SSM - object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; - // здесь хранятся выведенные типы лямбд или null если типы явно заданы - for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) - { - var laminftypeK = - fld.formal_parameters.params_list[k].vars_type as - SyntaxTree.lambda_inferred_type; - if (laminftypeK == null) - realparamstype[k] = null; - else realparamstype[k] = laminftypeK.real_type; - } - - // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим - var restype = fld.return_type as SyntaxTree.lambda_inferred_type; - object realrestype = null; - if (restype != null) - realrestype = restype.real_type; - - LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type, fld, this); - fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; - //lroman - fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); - // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! - - //contextChanger.SaveContextAndUpToNearestDefSect(); - try - { - exprs1[exprCounter] = convert_strong(en); - - type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; - type_node resformaltype = fld.RealSemTypeOfResult as type_node; - var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность - if (bbb) - { - GoodVersionsCountWithSameResType += 1; - spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. - } - - /*var tt = fn.parameters[exprCounter].type as compiled_type_node; - if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) - { - resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func - тип возвращаемого значения - var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность - if (bbb) - { - GoodVersionsCountWithSameResType += 1; - spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. - } - }*/ - } - catch - { - throw; - } - finally - { - LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); - // восстанавливаем сохраненный тип возвращаемого значения - if (restype != null) - restype.real_type = realrestype; - // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно - for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) - { - var laminftypeK = - fld.formal_parameters.params_list[k].vars_type as - SyntaxTree.lambda_inferred_type; - if (laminftypeK != null) - laminftypeK.real_type = realparamstype[k]; - } - - fld.lambda_name = lambdaName; //lroman Восстанавливаем имена - fld.lambda_visit_mode = fl; - } - - //contextChanger.RestoreCurrentContext(); - exprCounter++; - } - } - /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так - { - spfnum = -2; - break; - }*/ - - if (GoodVersionsCountWithSameResType == 0) - spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения - GoodVersionsCount += 1; - for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо - exprs[j] = exprs1[j]; - } - catch (Exception e) - { - // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать - //contextChanger.RestoreCurrentContext(); - lastmultex = e; - } - } - if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения - throw new SeveralFunctionsCanBeCalled(loc, spf); - if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд - { - throw lastmultex; - //throw new NoFunctionWithSameArguments(subloc2, false); - } - - var kk = 0; - foreach (SyntaxTree.expression en in syntax_nodes_parameters) - //lroman окончательно подставить типы в лямбды - { - if (!(en is SyntaxTree.function_lambda_definition)) - { - kk++; - continue; - } - else - { - LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, - en as SyntaxTree.function_lambda_definition, this); - exprs[kk] = convert_strong(en); - kk++; - } - } - } - // SSM 21.05.14 end - LambdaHelper.processingLambdaParametersForTypeInference--; - - fnn = convertion_data_and_alghoritms.select_function(exprs, sil, loc); - } - //lroman// - #endregion - - else - { - fnn = convertion_data_and_alghoritms.select_function(exprs, sil, loc); - } - } - catch (NoFunctionWithSameParametresNum e) - { - e.is_constructor = true; - throw; - } - return create_static_method_call_with_params(fnn, loc, tn, false, exprs); - } - - private expression_node clip_expression_if_need(expression_node expr, type_node tn) - { - if (!(tn is short_string_type_node) && tn.type_special_kind != SemanticTree.type_special_kind.set_type) - return expr; - if (tn is short_string_type_node) - { - return convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(expr,SystemLibrary.SystemLibrary.string_type),new int_const_node((tn as short_string_type_node).Length,null)); - } - else if (tn.type_special_kind == SemanticTree.type_special_kind.set_type && tn.element_type != null) - { - ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; - if (oti != null) - { - base_function_call cmc = null; - if (SystemLibrary.SystemLibInitializer.ClipFunction.sym_info is common_namespace_function_node) - cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node, null); - else - cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as compiled_function_node, null); - cmc.parameters.AddElement(expr); - cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); - cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); - cmc.ret_type = tn; - return cmc; - } - else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) - { - base_function_call cmc = null; - if (SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info is common_namespace_function_node) - cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node, null); - else - cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as compiled_function_node, null); - cmc.parameters.AddElement(expr); - cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length, null)); - cmc.ret_type = tn; - return cmc; - } - } - return expr; - } - - public override void visit(SyntaxTree.new_expr _new_expr) - { - type_node tn = ret.visit(_new_expr.type); - if (tn is generic_instance_type_node gitn) // SSM 07/08/19 #2070 - gitn._is_abstract = gitn.original_generic.IsAbstract; - //if (tn == SystemLibrary.SystemLibrary.void_type) - // AddError(new VoidNotValid(get_location(_new_expr.type))); - if (tn.IsDelegate && !_new_expr.new_array) - AddError(get_location(_new_expr), "CONSTRUCTOR_CALL_FOR_DELEGATE_TYPES_IS_FORBIDDEN"); - check_for_type_allowed(tn,get_location(_new_expr.type)); - location loc = get_location(_new_expr); - expressions_list exprs = null; - var lambdas_are_in_parameters = false; - var syntax_nodes_parameters = _new_expr.params_list == null - ? new List() - : _new_expr.params_list.expressions; - - if (_new_expr.params_list != null) - { - exprs = new expressions_list(); - foreach (SyntaxTree.expression en in _new_expr.params_list.expressions) - { - if (en is SyntaxTree.function_lambda_definition) - { - lambdas_are_in_parameters = true; - ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; - } - exprs.AddElement(convert_strong(en)); - } - } - else - exprs = new expressions_list(); - if (_new_expr.new_array) - { - check_using_static_class(tn, get_location(_new_expr.type)); - //if (exprs.Count == 1) - { - //new typename[size] - type_node atn = convertion_data_and_alghoritms.type_constructor.create_unsized_array(tn, context.converted_namespace, exprs.Count, loc); - //тип элементов - typeof_operator to = new typeof_operator(tn, loc); - List lst = new List(); - //размер - for (int i=0; i 1) - { - foreach (expression_node expr in lst) - if (!(expr is int_const_node)) - AddError(expr.location, "CONSTANT_EXPRESSION_EXPECTED"); - if (_new_expr.array_init_expr.elements == null) - AddError(get_location(_new_expr.array_init_expr), "ARRAY_CONST_EXPECTED"); - _new_expr.array_init_expr = get_possible_array_const(_new_expr.array_init_expr,atn) as SyntaxTree.array_const; - expression_node e = convert_strong(_new_expr.array_init_expr); - if (e is array_initializer) - { - array_initializer tmp = e as array_initializer; - for (int i=0; i>(lambdas_are_in_parameters, syntax_nodes_parameters))); - } - - public override void visit(SyntaxTree.where_type_specificator_list node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.where_definition node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.where_definition_list node) - { - throw new NotSupportedError(get_location(node)); - } - - private bool can_evaluate_size(type_node tn) - { - if (tn is compiled_type_node ctn1) - { - if (tn.type_special_kind == SemanticTree.type_special_kind.array_wrapper || tn.type_special_kind == SemanticTree.type_special_kind.set_type - || tn.type_special_kind == SemanticTree.type_special_kind.short_string || tn.type_special_kind == SemanticTree.type_special_kind.typed_file || tn.type_special_kind == SemanticTree.type_special_kind.text_file - || tn.type_special_kind == SemanticTree.type_special_kind.binary_file || tn.type_special_kind == SemanticTree.type_special_kind.array_kind) - return true; - if (tn.type_special_kind == SemanticTree.type_special_kind.diap_type || tn.type_special_kind == SemanticTree.type_special_kind.enum_kind) - return true; - if (tn.IsPointer) - return true; - if (tn.is_generic_parameter || tn.is_generic_type_definition || tn.is_generic_type_instance) - return false; - /*if (ctn1.compiled_type == typeof(System.IntPtr) || ctn1.compiled_type == typeof(System.UIntPtr)) - return false;*/ - } - if (tn is common_type_node) - { - common_type_node ctn = tn as common_type_node; - - if (ctn.type_special_kind == SemanticTree.type_special_kind.diap_type || ctn.type_special_kind == SemanticTree.type_special_kind.enum_kind) - return true; - if (tn.type_special_kind == SemanticTree.type_special_kind.array_wrapper || tn.type_special_kind == SemanticTree.type_special_kind.set_type || tn.type_special_kind == SemanticTree.type_special_kind.short_string - || tn.type_special_kind == SemanticTree.type_special_kind.typed_file || tn.type_special_kind == SemanticTree.type_special_kind.text_file - || tn.type_special_kind == SemanticTree.type_special_kind.binary_file || tn.type_special_kind == SemanticTree.type_special_kind.array_kind) - return true; - if (tn.IsPointer) - return true; - - if (tn.is_generic_parameter || tn.is_generic_type_definition || tn.is_generic_type_instance) - return false; - foreach (class_field cf in ctn.fields) - if (!cf.IsStatic) - if (!can_evaluate_size(cf.type)) return false; - - } - return true; - } - - private expression_node make_sizeof_operator(type_node tn, location loc) - { - return new sizeof_operator(tn,loc); - } - - public override void visit(SyntaxTree.sizeof_operator node) - { - if (node.type_def != null && node.type_def is SyntaxTree.named_type_reference) - { - SyntaxTree.named_type_reference ntr = node.type_def as SyntaxTree.named_type_reference; - type_node tn = find_type(ntr, get_location(ntr)); - switch (tn.type_special_kind) - { - case SemanticTree.type_special_kind.enum_kind: - if (tn is compiled_type_node ctn) - { - return_value(new int_const_node(System.Runtime.InteropServices.Marshal.SizeOf(ctn.compiled_type.GetEnumUnderlyingType()), get_location(ntr))); break; - } - else - { - return_value(new int_const_node(sizeof(int), get_location(ntr))); break; - } - default: - if (tn.is_generic_parameter || tn.is_generic_type_definition || tn.is_generic_type_instance) - { - AddError(get_location(ntr), "OPERATOR_SIZEOF_CAN_NOT_BE_USED_WITH_GENERIC_TYPE"); - } - if (!can_evaluate_size(tn)) - AddError(get_location(ntr), "CANNOT_EVALUATE_SIZE", tn.name); - return_value(make_sizeof_operator(tn, get_location(node))); - break; - } - } - else - throw new NotSupportedError(get_location(node)); - - } - - public override void visit(SyntaxTree.typeof_operator node) - { - return_value(new typeof_operator(find_type(node.type_name, get_location(node.type_name)), get_location(node))); - } - - public override void visit(SyntaxTree.compiler_directive node) - { - if (node.Name.text.ToLower() == compiler_string_consts.compiler_directive_faststrings) - { - SemanticRules.FastStrings = true; - return; - } - if (node.Name.text.ToLower() == compiler_string_consts.compiler_directive_nullbasedstrings) - { - SemanticRules.NullBasedStrings = node.Directive.text.ToLower() == compiler_string_consts.true_const_name; - return; - } - if (node.Name.text.ToLower() == compiler_string_consts.compiler_directive_nullbasedstrings_ON) - { - SemanticRules.NullBasedStrings = true; - return; - } - if (node.Name.text.ToLower() == compiler_string_consts.compiler_directive_nullbasedstrings_OFF) - { - SemanticRules.NullBasedStrings = false; - return; - } - if (node.Name.text.ToLower() == compiler_string_consts.compiler_directive_initstring_as_empty_ON) - { - SemanticRules.InitStringAsEmptyString = true; - return; - } - if (node.Name.text.ToLower() == compiler_string_consts.compiler_directive_initstring_as_empty_OFF) - { - SemanticRules.InitStringAsEmptyString = false; - return; - } - if (node.Name.text == "platform" && node.Directive.text.ToLower() == "native") - { - SemanticRules.GenerateNativeCode = true; - - - return; - } - } - - public override void visit(SyntaxTree.operator_name_ident node) - { - throw new NotSupportedError(get_location(node)); - } - - public override void visit(SyntaxTree.var_statement node) - { - visit(node.var_def); - ret.reset(); // SSM 19.01.17 не возвращать семантическое значение т.к. ничего не нужно добавлять в текущий список операторов!! - } - - public override void visit(SyntaxTree.expression_as_statement node) - { - return_value((statement_node)convert_strong(node.expr)); - } - - //ssyy - public void generate_inherit_constructors() - { - common_type_node _ctn = context.converted_type; - if (_ctn == null) - { - throw new CompilerInternalError("Can generate inherited constructors only in class."); - } - if (_ctn.IsStatic) - return; - if (_ctn.has_user_defined_constructor) - { - //Пользователь определил хотя бы один конструктор, никакие конструкторы не наследуем. - return; - } - //Получили список процедур предка, имеющих имя Create - List sil = _ctn.base_type.find_in_type(compiler_string_consts.default_constructor_name, _ctn.base_type.Scope); - delete_inherited_constructors(ref sil, _ctn.base_type); - if (sil != null) - { - foreach(SymbolInfo si in sil) - { - function_node fn = si.sym_info as function_node; - compiled_constructor_node pconstr = fn as compiled_constructor_node; - common_method_node mconstr = fn as common_method_node; - //Если это конструктор... - if (pconstr != null || - mconstr != null && mconstr.is_constructor) - { - //Генерируем унаследованный конструктор - location loc = null; - SemanticTree.polymorphic_state ps; - if (mconstr != null) - { - loc = mconstr.loc; - ps = mconstr.polymorphic_state; - } - else //значит (pconstr != null) - { - ps = pconstr.polymorphic_state; - } - if (pconstr != null) - context.set_field_access_level(pconstr.field_access_level); - else - context.set_field_access_level(mconstr.field_access_level); - +// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) +//Посетитель синтаксического дерева. +using System; +using System.Linq; +using System.Collections; +using System.Collections.Generic; +using PascalABCCompiler.SyntaxTree; +using PascalABCCompiler.TreeRealization; + +using SyntaxTreeBuilder = PascalABCCompiler.SyntaxTree.SyntaxTreeBuilder; +using SymTable = SymbolTable; +using array_const = PascalABCCompiler.TreeRealization.array_const; +using compiler_directive = PascalABCCompiler.TreeRealization.compiler_directive; +using empty_statement = PascalABCCompiler.TreeRealization.empty_statement; +using for_node = PascalABCCompiler.TreeRealization.for_node; +using goto_statement = PascalABCCompiler.TreeRealization.goto_statement; +using if_node = PascalABCCompiler.TreeRealization.if_node; +using labeled_statement = PascalABCCompiler.TreeRealization.labeled_statement; +using question_colon_expression = PascalABCCompiler.TreeRealization.question_colon_expression; +using repeat_node = PascalABCCompiler.TreeRealization.repeat_node; +using sizeof_operator = PascalABCCompiler.TreeRealization.sizeof_operator; +using typeof_operator = PascalABCCompiler.TreeRealization.typeof_operator; +using while_node = PascalABCCompiler.TreeRealization.while_node; +using TreeConverter.LambdaExpressions.Closure; +using TreeConverter.LambdaExpressions; + +namespace PascalABCCompiler.TreeConverter +{ + // Сахарный узел синтаксического дерева. Не генерируется автоматически, поскольку содержит ссылку на узел семантического дерева + // Нужен только при генерации синтаксических узлов на семантическом уровне, т.е. для синтаксического сахара +/* public class semantic_type_node : SyntaxTree.type_definition + { + public type_node type { get; set; } + public semantic_type_node(type_node t) + { + type = t; + } + }*/ + + public partial class syntax_tree_visitor : SyntaxTree.WalkingVisitorNew // SSM 02.01.17 менять на визитор с другим порядком обхода можно, но бессмысленно + // Порядок обхода не важен поскольку все узлы visit переопределяются + // SSM 02.01.17 Использование ReplaceStatement из BaseChangeVisitor плохо изучено - что-то не работает + // Поэтому используется явный Parent и ReplaceStatement из узла statement_list + { + public SymbolTable.PrimaryScope MainScope + { + get + { + var a = SymbolTable.ScopeTable.Where(s => (s.GetType() == typeof(SymbolTable.UnitInterfaceScope))).Skip(1); + return new SymbolTable.PrimaryScope(a.Last()); + } + } + + public SymbolTable.PrimaryScope CurrentScope + { + get + { + if(context.CurrentScope != null) + return new SymbolTable.PrimaryScope(context.CurrentScope); + return null; + } + } + + public convertion_data_and_alghoritms convertion_data_and_alghoritms; + + internal returner ret; + + internal document current_document; + + public compilation_context context; + public ContextChanger contextChanger; + + internal using_namespace_list using_list = new using_namespace_list(); + internal using_namespace_list interface_using_list = new using_namespace_list(); + + // SSM 6/08/15 Стек для хранения вложенных лямбд для одной цели - вычислить истинный тип выражения, присваиваемого Result. Это нужно для выбора перегруженной функции, у которой параметр лямбда и один из типов возвращаемого значения в точности совпадает с типом возвращаемого значения лямбды + internal Stack stflambda = new Stack(); + + //TODO: Загнать в request. + motivation_keeper motivation_keeper = new motivation_keeper(); + + private PascalABCCompiler.TreeRealization.unit_node_list _referenced_units; + + private common_unit_node _compiled_unit; + + private common_unit_node _system_unit; + internal bool debug=true; + internal bool debugging=false; + internal List ErrorsList; + internal List WarningsList; + internal Dictionary docs; + public bool for_native_code = false; + internal Dictionary DirectivesToNodesLinks; + public bool ThrowCompilationError = true; + public bool MustVisitBody = true; + public LambdaProcessingState lambdaProcessingState = LambdaProcessingState.None; //lroman + + #region (MikhailoMMX) Положение визитора относительно параллельных конструкций + public ParallelPosition CurrentParallelPosition = ParallelPosition.Outside; + #endregion + + private int num = 0; + + public string UniqueNumStr() + { + num++; + return num.ToString(); + } + + internal Errors.Error LastError() + { + Errors.Error err = ErrorsList[ErrorsList.Count-1]; + ErrorsList.RemoveAt(ErrorsList.Count - 1); + return err; + } + + internal void RemoveLastError() + { + if (ErrorsList.Count > 0) + ErrorsList.RemoveAt(ErrorsList.Count - 1); + } + + internal void AddError(Errors.Error err, bool shouldReturn=false) + { + if (ThrowCompilationError || !shouldReturn /*|| err.MustThrow && !shouldReturn*/) + { + throw err; + } + else + { + ErrorsList.Add(err); + } + } + + internal void AddError(location loc, string ErrResourceString, params object[] values) + { + Errors.Error err = new SimpleSemanticError(loc, ErrResourceString, values); + if (ThrowCompilationError) + { + throw err; + } + else + { + ErrorsList.Add(err); + } + } + + internal void AddWarning(Errors.CompilerWarning err) + { + WarningsList.Add(err); + } + + private bool _record_created = false; + + private bool with_class_name=false; + + internal bool from_pabc_dll = false; + + private bool type_section_converting = false; + + private Dictionary set_intls = new Dictionary(); + + //(ssyy) Дополнительные ограничения на параметры generic-типа. + //Например, возможность объявить указатель на этот тип-параметр. + internal Dictionary generic_param_abilities = + new Dictionary(); + + private GenericParameterAbilities get_type_abilities(type_node t) + { + GenericParameterAbilities gpa; + if (generic_param_abilities.TryGetValue(t, out gpa)) return gpa; + gpa = new GenericParameterAbilities(); + generic_param_abilities.Add(t, gpa); + return gpa; + } + + private void internal_reset() + { + PascalABCCompiler.SystemLibrary.SystemLibInitializer.initialization_properties init_properties = + new PascalABCCompiler.SystemLibrary.SystemLibInitializer.initialization_properties(); + + init_properties.break_executor = make_break_node; + init_properties.continue_executor = make_continue_node; + init_properties.exit_executor = make_exit_node; + + _system_unit = SystemLibrary.SystemLibInitializer.make_system_unit(convertion_data_and_alghoritms.symbol_table, + init_properties); + SystemLibrary.SystemLibrary.system_unit = _system_unit; + generic_convertions.reset_generics(); + generic_convertions.visitor = this; + _record_created = false; + RefTypesForCheckPointersTypeForDotNetFramework.Clear(); + reset_for_interface(); + _is_interface_part = false; + with_class_name = false; + disable_order_independ = false; + generic_param_abilities.Clear(); + current_converted_method_not_in_class_defined = false; + assign_is_converting = false; + motivation_keeper.reset(); + SystemLibrary.SystemLibInitializer.NeedsToRestore.Clear(); + type_section_converting = false; + ThrowCompilationError = true; + #region MikhailoMMX, реинициализация класса OpenMP + OpenMP.InternalReset(); + CurrentParallelPosition = ParallelPosition.Outside; + #endregion + + lambdaProcessingState = LambdaProcessingState.None; //lroman + CapturedVariablesSubstitutionClassGenerator.Reset(); + } + + public syntax_tree_visitor() + { + convertion_data_and_alghoritms = new convertion_data_and_alghoritms(this); + ret = new returner(this); + context = new compilation_context(convertion_data_and_alghoritms, this); + contextChanger = new ContextChanger(context); + internal_reset(); + } + + + private void release_system_module() + { + SystemUnitAssigned = false; + SystemLibrary.SystemLibInitializer.format_function = null; + SystemLibrary.SystemLibInitializer.read_procedure = null; + SystemLibrary.SystemLibInitializer.write_procedure = null; + SystemLibrary.SystemLibInitializer.writeln_procedure = null; + SystemLibrary.SystemLibInitializer.readln_procedure = null; + SystemLibrary.SystemLibInitializer.TextFileType = null; + SystemLibrary.SystemLibInitializer.TextFileInitProcedure = null; + SystemLibrary.SystemLibInitializer.BinaryFileType = null; + SystemLibrary.SystemLibInitializer.AbstractBinaryFileType = null; + SystemLibrary.SystemLibInitializer.PointerOutputType = null; + SystemLibrary.SystemLibInitializer.BinaryFileInitProcedure = null; + SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure = null; + SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure = null; + SystemLibrary.SystemLibInitializer.TypedFileType = null; + SystemLibrary.SystemLibInitializer.TypedFileInitProcedure = null; + SystemLibrary.SystemLibInitializer.TypedFileReadProcedure = null; + SystemLibrary.SystemLibInitializer.ShortStringType = null; + SystemLibrary.SystemLibInitializer.ShortStringTypeInitProcedure = null; + SystemLibrary.SystemLibInitializer.TypedSetType = null; + SystemLibrary.SystemLibInitializer.SetUnionProcedure = null; + SystemLibrary.SystemLibInitializer.SetIntersectProcedure = null; + SystemLibrary.SystemLibInitializer.SetSubtractProcedure = null; + SystemLibrary.SystemLibInitializer.InSetProcedure = null; + SystemLibrary.SystemLibInitializer.CreateSetProcedure = null; + SystemLibrary.SystemLibInitializer.TypedSetInitProcedure = null; + SystemLibrary.SystemLibInitializer.IncludeProcedure = null; + SystemLibrary.SystemLibInitializer.ExcludeProcedure = null; + SystemLibrary.SystemLibInitializer.DiapasonType = null; + SystemLibrary.SystemLibInitializer.CreateDiapason = null; + SystemLibrary.SystemLibInitializer.CreateObjDiapason = null; + SystemLibrary.SystemLibInitializer.CompareSetEquals = null; + SystemLibrary.SystemLibInitializer.CompareSetInEquals = null; + SystemLibrary.SystemLibInitializer.CompareSetLess = null; + SystemLibrary.SystemLibInitializer.CompareSetLessEqual = null; + SystemLibrary.SystemLibInitializer.CompareSetGreater = null; + SystemLibrary.SystemLibInitializer.CompareSetGreaterEqual = null; + SystemLibrary.SystemLibInitializer.IncProcedure = null; + SystemLibrary.SystemLibInitializer.DecProcedure = null; + SystemLibrary.SystemLibInitializer.SuccFunction = null; + SystemLibrary.SystemLibInitializer.PredFunction = null; + SystemLibrary.SystemLibInitializer.OrdFunction = null; + SystemLibrary.SystemLibInitializer.TypedSetInitProcedureWithBounds = null; + SystemLibrary.SystemLibInitializer.TypedSetInitWithShortString = null; + SystemLibrary.SystemLibInitializer.AssignSetProcedure = null; + SystemLibrary.SystemLibInitializer.AssignSetProcedureWithBounds = null; + SystemLibrary.SystemLibInitializer.ClipProcedure = null; + SystemLibrary.SystemLibInitializer.ClipFunction = null; + SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction = null; + SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure = null; + SystemLibrary.SystemLibInitializer.ClipShortStringProcedure = null; + SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure = null; + SystemLibrary.SystemLibInitializer.SetCharInShortStringProcedure = null; + SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure = null; + SystemLibrary.SystemLibInitializer.SetLengthProcedure = null; + SystemLibrary.SystemLibInitializer.read_short_string_procedure = null; + SystemLibrary.SystemLibInitializer.read_short_string_from_file_procedure = null; + SystemLibrary.SystemLibInitializer.InsertProcedure = null; + SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure = null; + SystemLibrary.SystemLibInitializer.DeleteProcedure = null; + SystemLibrary.SystemLibInitializer.LowFunction = null; + SystemLibrary.SystemLibInitializer.HighFunction = null; + SystemLibrary.SystemLibInitializer.CheckCanUsePointerOnTypeProcedure = null; + SystemLibrary.SystemLibInitializer.CheckCanUseTypeForBinaryFilesProcedure = null; + SystemLibrary.SystemLibInitializer.CheckCanUseTypeForTypedFilesProcedure = null; + SystemLibrary.SystemLibInitializer.RuntimeDetermineTypeFunction = null; + SystemLibrary.SystemLibInitializer.RuntimeInitializeFunction = null; + SystemLibrary.SystemLibInitializer.PointerToStringFunction = null; + SystemLibrary.SystemLibInitializer.GetRuntimeSizeFunction = null; + SystemLibrary.SystemLibInitializer.PointerOutputConstructor = null; + SystemLibrary.SystemLibInitializer.StrProcedure = null; + SystemLibrary.SystemLibInitializer.ChrUnicodeFunction = null; + SystemLibrary.SystemLibInitializer.AssertProcedure = null; + SystemLibrary.SystemLibInitializer.CheckRangeFunction = null; + SystemLibrary.SystemLibInitializer.CheckCharRangeFunction = null; + SystemLibrary.SystemLibInitializer.CopyWithSizeFunction = null; + SystemLibrary.SystemLibInitializer.ArrayCopyFunction = null; + SystemLibrary.SystemLibInitializer.ObjectType = null; + SystemLibrary.SystemLibInitializer.StringType = null; + SystemLibrary.SystemLibInitializer.ConfigVariable = null; + SystemLibrary.SystemLibInitializer.PascalABCVersion = null; + } + + internal bool SystemUnitAssigned = false; + + public static void init_system_module(common_unit_node psystem_unit) + { + SystemLibrary.SystemLibInitializer.format_function = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.format_procedure_name); + SystemLibrary.SystemLibInitializer.read_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.read_procedure_name); + SystemLibrary.SystemLibInitializer.write_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.write_procedure_name); + SystemLibrary.SystemLibInitializer.writeln_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.writeln_procedure_name); + SystemLibrary.SystemLibInitializer.readln_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.readln_procedure_name); + SystemLibrary.SystemLibInitializer.TextFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.text_file_name_type_name); + SystemLibrary.SystemLibInitializer.TextFileInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TextFileInitProcedureName); + SystemLibrary.SystemLibInitializer.BinaryFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.BinaryFileTypeName); + SystemLibrary.SystemLibInitializer.AbstractBinaryFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AbstractBinaryFileTypeName); + SystemLibrary.SystemLibInitializer.PointerOutputType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PointerOutputTypeName); + SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.BinaryFileReadProcedureName); + SystemLibrary.SystemLibInitializer.BinaryFileInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.BinaryFileInitProcedureName); + SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.StringDefaultPropertySetProcedureName); + SystemLibrary.SystemLibInitializer.TypedFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedFileTypeName); + SystemLibrary.SystemLibInitializer.TypedFileInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedFileInitProcedureName); + SystemLibrary.SystemLibInitializer.TypedFileReadProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedFileReadProcedureName); + SystemLibrary.SystemLibInitializer.ClipShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipShortString); + SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.GetCharInShortString); + SystemLibrary.SystemLibInitializer.SetCharInShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.SetCharInShortString); + //SystemLibrary.SystemLibInitializer.ShortStringType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ShortStringTypeName); + //SystemLibrary.SystemLibInitializer.ShortStringTypeInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ShortStringTypeInitProcedure); + SystemLibrary.SystemLibInitializer.TypedSetType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.set_name); + SystemLibrary.SystemLibInitializer.TypedSetInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedSetInitProcedure); + SystemLibrary.SystemLibInitializer.SetUnionProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.union_of_set); + SystemLibrary.SystemLibInitializer.SetIntersectProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.intersect_of_set); + SystemLibrary.SystemLibInitializer.SetSubtractProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.subtract_of_set); + SystemLibrary.SystemLibInitializer.InSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.in_set); + SystemLibrary.SystemLibInitializer.CreateSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CreateSetProcedure); + SystemLibrary.SystemLibInitializer.IncludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.IncludeProcedure); + SystemLibrary.SystemLibInitializer.ExcludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ExcludeProcedure); + SystemLibrary.SystemLibInitializer.DiapasonType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.DiapasonType); + SystemLibrary.SystemLibInitializer.CreateDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CreateDiapason); + SystemLibrary.SystemLibInitializer.CreateObjDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CreateObjDiapason); + SystemLibrary.SystemLibInitializer.CompareSetEquals = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetEquals); + SystemLibrary.SystemLibInitializer.CompareSetInEquals = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetInEquals); + SystemLibrary.SystemLibInitializer.CompareSetLess = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetLess); + SystemLibrary.SystemLibInitializer.CompareSetLessEqual = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetLessEqual); + SystemLibrary.SystemLibInitializer.CompareSetGreater = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetGreater); + SystemLibrary.SystemLibInitializer.CompareSetGreaterEqual = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetGreaterEqual); + SystemLibrary.SystemLibInitializer.IncProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.IncProcedure); + SystemLibrary.SystemLibInitializer.DecProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.DecProcedure); + SystemLibrary.SystemLibInitializer.SuccFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.SuccFunction); + SystemLibrary.SystemLibInitializer.PredFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PredFunction); + SystemLibrary.SystemLibInitializer.OrdFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.OrdFunction); + SystemLibrary.SystemLibInitializer.TypedSetInitProcedureWithBounds = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedSetInitProcedureWithBounds); + SystemLibrary.SystemLibInitializer.TypedSetInitWithShortString = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedSetInitWithShortString); + SystemLibrary.SystemLibInitializer.AssignSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AssignSetProcedure); + SystemLibrary.SystemLibInitializer.AssignSetProcedureWithBounds = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AssignSetProcedureWithBounds); + SystemLibrary.SystemLibInitializer.ClipProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipProcedure); + SystemLibrary.SystemLibInitializer.ClipFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipFunction); + SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipShortStringInSetFunction); + SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipShortStringInSetProcedure); + SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.set_length_for_short_string); + SystemLibrary.SystemLibInitializer.SetLengthProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.set_length_procedure_name); + SystemLibrary.SystemLibInitializer.read_short_string_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.read_short_string); + SystemLibrary.SystemLibInitializer.read_short_string_from_file_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.read_short_string_from_file); + SystemLibrary.SystemLibInitializer.InsertProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit,compiler_string_consts.Insert); + SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit,compiler_string_consts.InsertInShortString); + SystemLibrary.SystemLibInitializer.DeleteProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit,compiler_string_consts.Delete); + SystemLibrary.SystemLibInitializer.LowFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit,compiler_string_consts.Low); + SystemLibrary.SystemLibInitializer.HighFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit,compiler_string_consts.High); + SystemLibrary.SystemLibInitializer.CheckCanUsePointerOnTypeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CheckCanUsePointerOnType_proc_name); + SystemLibrary.SystemLibInitializer.CheckCanUseTypeForBinaryFilesProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CheckCanUseTypeForBinaryFiles_proc_name); + SystemLibrary.SystemLibInitializer.CheckCanUseTypeForTypedFilesProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CheckCanUseTypeForTypedFiles_proc_name); + SystemLibrary.SystemLibInitializer.RuntimeDetermineTypeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.RuntimeDetermineType_func_name); + SystemLibrary.SystemLibInitializer.RuntimeInitializeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.RuntimeInitializeFunction_func_name); + SystemLibrary.SystemLibInitializer.PointerToStringFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PointerToStringFunction_func_name); + SystemLibrary.SystemLibInitializer.GetRuntimeSizeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.GetRuntimeSizeFunction_func_name); + SystemLibrary.SystemLibInitializer.StrProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.StrProcedure_func_name); + SystemLibrary.SystemLibInitializer.PascalABCVersion = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PascalABCVersion_func_name); + SystemLibrary.SystemLibInitializer.ChrUnicodeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ChrUnicodeFunction_func_name); + SystemLibrary.SystemLibInitializer.AssertProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AssertProcedure); + SystemLibrary.SystemLibInitializer.CheckRangeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.check_in_range); + SystemLibrary.SystemLibInitializer.CheckCharRangeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.check_in_range_char); + SystemLibrary.SystemLibInitializer.CopyWithSizeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CopyWithSizeFunction); + SystemLibrary.SystemLibInitializer.ArrayCopyFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ArrayCopyFunction); + SystemLibrary.SystemLibInitializer.ConfigVariable = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.config_variable_name); + //SystemLibrary.SystemLibrary.make_type_conversion(SystemLibrary.SystemLibInitializer.ShortStringType.sym_info as type_node,SystemLibrary.SystemLibrary.string_type,type_compare.less_type,SemanticTree.basic_function_type.none,true); + //SystemLibrary.SystemLibrary.make_type_conversion(SystemLibrary.SystemLibrary.string_type,SystemLibrary.SystemLibInitializer.ShortStringType.sym_info as type_node,type_compare.greater_type,SemanticTree.basic_function_type.none,true); + if (SystemLibrary.SystemLibInitializer.TextFileType.Found) + SystemLibrary.SystemLibInitializer.TextFileType.TypeNode.type_special_kind = PascalABCCompiler.SemanticTree.type_special_kind.text_file; + if (SemanticRules.GenerateNativeCode) + { + SystemLibrary.SystemLibInitializer.ObjectType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ObjectType); + if (SystemLibrary.SystemLibInitializer.ObjectType.Found) + SemanticRules.ClassBaseType = SystemLibrary.SystemLibInitializer.ObjectType.sym_info as TreeRealization.type_node; + SystemLibrary.SystemLibInitializer.StringType = new PascalABCCompiler.SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.StringType); + if (SystemLibrary.SystemLibInitializer.StringType.Found) + SemanticRules.StringType = SystemLibrary.SystemLibInitializer.StringType.sym_info as TreeRealization.type_node; + } + } + + public static void init_system_module_from_dll(dot_net_unit_node psystem_unit) + { + SystemLibrary.SystemLibInitializer.format_function = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.format_procedure_name); + SystemLibrary.SystemLibInitializer.read_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.read_procedure_name); + SystemLibrary.SystemLibInitializer.write_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.write_procedure_name); + SystemLibrary.SystemLibInitializer.writeln_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.writeln_procedure_name); + SystemLibrary.SystemLibInitializer.readln_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.readln_procedure_name); + SystemLibrary.SystemLibInitializer.TextFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.text_file_name_type_name); + SystemLibrary.SystemLibInitializer.TextFileInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TextFileInitProcedureName); + SystemLibrary.SystemLibInitializer.BinaryFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.BinaryFileTypeName); + SystemLibrary.SystemLibInitializer.AbstractBinaryFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AbstractBinaryFileTypeName); + SystemLibrary.SystemLibInitializer.PointerOutputType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PointerOutputTypeName); + SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.BinaryFileReadProcedureName); + SystemLibrary.SystemLibInitializer.BinaryFileInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.BinaryFileInitProcedureName); + SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.StringDefaultPropertySetProcedureName); + SystemLibrary.SystemLibInitializer.TypedFileType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedFileTypeName); + SystemLibrary.SystemLibInitializer.TypedFileInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedFileInitProcedureName); + SystemLibrary.SystemLibInitializer.TypedFileReadProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedFileReadProcedureName); + SystemLibrary.SystemLibInitializer.ClipShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipShortString); + SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.GetCharInShortString); + SystemLibrary.SystemLibInitializer.SetCharInShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.SetCharInShortString); + //SystemLibrary.SystemLibInitializer.ShortStringType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ShortStringTypeName); + //SystemLibrary.SystemLibInitializer.ShortStringTypeInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ShortStringTypeInitProcedure); + SystemLibrary.SystemLibInitializer.TypedSetType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.set_name); + SystemLibrary.SystemLibInitializer.TypedSetInitProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedSetInitProcedure); + SystemLibrary.SystemLibInitializer.SetUnionProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.union_of_set); + SystemLibrary.SystemLibInitializer.SetIntersectProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.intersect_of_set); + SystemLibrary.SystemLibInitializer.SetSubtractProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.subtract_of_set); + SystemLibrary.SystemLibInitializer.InSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.in_set); + SystemLibrary.SystemLibInitializer.CreateSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CreateSetProcedure); + SystemLibrary.SystemLibInitializer.IncludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.IncludeProcedure); + SystemLibrary.SystemLibInitializer.ExcludeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ExcludeProcedure); + SystemLibrary.SystemLibInitializer.DiapasonType = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.DiapasonType); + SystemLibrary.SystemLibInitializer.CreateDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CreateDiapason); + SystemLibrary.SystemLibInitializer.CreateObjDiapason = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CreateObjDiapason); + SystemLibrary.SystemLibInitializer.CompareSetEquals = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetEquals); + SystemLibrary.SystemLibInitializer.CompareSetInEquals = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetInEquals); + SystemLibrary.SystemLibInitializer.CompareSetLess = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetLess); + SystemLibrary.SystemLibInitializer.CompareSetLessEqual = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetLessEqual); + SystemLibrary.SystemLibInitializer.CompareSetGreater = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetGreater); + SystemLibrary.SystemLibInitializer.CompareSetGreaterEqual = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CompareSetGreaterEqual); + SystemLibrary.SystemLibInitializer.IncProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.IncProcedure); + SystemLibrary.SystemLibInitializer.DecProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.DecProcedure); + SystemLibrary.SystemLibInitializer.SuccFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.SuccFunction); + SystemLibrary.SystemLibInitializer.PredFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PredFunction); + SystemLibrary.SystemLibInitializer.OrdFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.OrdFunction); + SystemLibrary.SystemLibInitializer.TypedSetInitProcedureWithBounds = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedSetInitProcedureWithBounds); + SystemLibrary.SystemLibInitializer.TypedSetInitWithShortString = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.TypedSetInitWithShortString); + SystemLibrary.SystemLibInitializer.AssignSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AssignSetProcedure); + SystemLibrary.SystemLibInitializer.AssignSetProcedureWithBounds = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AssignSetProcedureWithBounds); + SystemLibrary.SystemLibInitializer.ClipProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipProcedure); + SystemLibrary.SystemLibInitializer.ClipFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipFunction); + SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipShortStringInSetFunction); + SystemLibrary.SystemLibInitializer.ClipShortStringInSetProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ClipShortStringInSetProcedure); + SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.set_length_for_short_string); + SystemLibrary.SystemLibInitializer.SetLengthProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.set_length_procedure_name); + SystemLibrary.SystemLibInitializer.read_short_string_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.read_short_string); + SystemLibrary.SystemLibInitializer.read_short_string_from_file_procedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.read_short_string_from_file); + SystemLibrary.SystemLibInitializer.InsertProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.Insert); + SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.InsertInShortString); + SystemLibrary.SystemLibInitializer.DeleteProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.Delete); + SystemLibrary.SystemLibInitializer.LowFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.Low); + SystemLibrary.SystemLibInitializer.HighFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.High); + SystemLibrary.SystemLibInitializer.CheckCanUsePointerOnTypeProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CheckCanUsePointerOnType_proc_name); + SystemLibrary.SystemLibInitializer.CheckCanUseTypeForBinaryFilesProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CheckCanUseTypeForBinaryFiles_proc_name); + SystemLibrary.SystemLibInitializer.CheckCanUseTypeForTypedFilesProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CheckCanUseTypeForTypedFiles_proc_name); + SystemLibrary.SystemLibInitializer.RuntimeDetermineTypeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.RuntimeDetermineType_func_name); + SystemLibrary.SystemLibInitializer.RuntimeInitializeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.RuntimeInitializeFunction_func_name); + SystemLibrary.SystemLibInitializer.PointerToStringFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PointerToStringFunction_func_name); + SystemLibrary.SystemLibInitializer.GetRuntimeSizeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.GetRuntimeSizeFunction_func_name); + SystemLibrary.SystemLibInitializer.StrProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.StrProcedure_func_name); + SystemLibrary.SystemLibInitializer.PascalABCVersion = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.PascalABCVersion_func_name); + SystemLibrary.SystemLibInitializer.ChrUnicodeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ChrUnicodeFunction_func_name); + SystemLibrary.SystemLibInitializer.AssertProcedure = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.AssertProcedure); + SystemLibrary.SystemLibInitializer.CheckRangeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.check_in_range); + SystemLibrary.SystemLibInitializer.CheckCharRangeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.check_in_range_char); + SystemLibrary.SystemLibInitializer.CopyWithSizeFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.CopyWithSizeFunction); + SystemLibrary.SystemLibInitializer.ArrayCopyFunction = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.ArrayCopyFunction); + SystemLibrary.SystemLibInitializer.ConfigVariable = new SystemLibrary.UnitDefinitionItem(psystem_unit, compiler_string_consts.config_variable_name); + //AddSpecialOperatorsToSetType(); + //SystemLibrary.SystemLibrary.make_type_conversion(SystemLibrary.SystemLibInitializer.ShortStringType.sym_info as type_node,SystemLibrary.SystemLibrary.string_type,type_compare.less_type,SemanticTree.basic_function_type.none,true); + //SystemLibrary.SystemLibrary.make_type_conversion(SystemLibrary.SystemLibrary.string_type,SystemLibrary.SystemLibInitializer.ShortStringType.sym_info as type_node,type_compare.greater_type,SemanticTree.basic_function_type.none,true); + if (SystemLibrary.SystemLibInitializer.TextFileType.Found) + SystemLibrary.SystemLibInitializer.TextFileType.TypeNode.type_special_kind = PascalABCCompiler.SemanticTree.type_special_kind.text_file; + } + + private void get_system_module(common_unit_node psystem_unit) + { + init_system_module(psystem_unit); + //esli zapustili v otladke, to vosstanovim mnozhestvo i procedury sozdanija diapasonov, inache ne budet rabotat + if (debugging) + { + List si = SystemLibrary.SystemLibInitializer.CreateDiapason.SymbolInfo; + si = SystemLibrary.SystemLibInitializer.CreateObjDiapason.SymbolInfo; + si = SystemLibrary.SystemLibInitializer.TypedSetType.SymbolInfo; + } + //if (SystemLibrary.SystemLibInitializer.TextFileType.Found) + // SystemLibrary.SystemLibInitializer.TextFileType.GetTypeNodeSpecials().type_special_kind = PascalABCCompiler.SemanticTree.type_special_kind.text_file; + SystemUnitAssigned = true; + CreateSpecialFields(psystem_unit); + } + + private void get_system_module_from_dll(dot_net_unit_node psystem_unit) + { + init_system_module_from_dll(psystem_unit); + //esli zapustili v otladke, to vosstanovim mnozhestvo i procedury sozdanija diapasonov, inache ne budet rabotat + if (debugging) + { + List si = SystemLibrary.SystemLibInitializer.CreateDiapason.SymbolInfo; + si = SystemLibrary.SystemLibInitializer.CreateObjDiapason.SymbolInfo; + si = SystemLibrary.SystemLibInitializer.TypedSetType.SymbolInfo; + } + //if (SystemLibrary.SystemLibInitializer.TextFileType.Found) + // SystemLibrary.SystemLibInitializer.TextFileType.GetTypeNodeSpecials().type_special_kind = PascalABCCompiler.SemanticTree.type_special_kind.text_file; + SystemUnitAssigned = true; + //CreateSpecialFields(psystem_unit); + } + + private void AddSpecialOperatorsToSetType() + { + if (SystemLibrary.SystemLibInitializer.TypedSetType.NotFound) + return; + common_type_node tctn = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as common_type_node; + tctn.type_special_kind = SemanticTree.type_special_kind.base_set_type; + tctn.scope.AddSymbol(compiler_string_consts.plus_name, SystemLibrary.SystemLibInitializer.SetUnionProcedure.SymbolInfo.FirstOrDefault()); + tctn.scope.AddSymbol(compiler_string_consts.mul_name, SystemLibrary.SystemLibInitializer.SetIntersectProcedure.SymbolInfo.FirstOrDefault()); + tctn.scope.AddSymbol(compiler_string_consts.in_name, SystemLibrary.SystemLibInitializer.InSetProcedure.SymbolInfo.FirstOrDefault()); + tctn.scope.AddSymbol(compiler_string_consts.minus_name, SystemLibrary.SystemLibInitializer.SetSubtractProcedure.SymbolInfo.FirstOrDefault()); + tctn.scope.AddSymbol(compiler_string_consts.gr_name, SystemLibrary.SystemLibInitializer.CompareSetGreater.SymbolInfo.FirstOrDefault()); + tctn.scope.AddSymbol(compiler_string_consts.greq_name, SystemLibrary.SystemLibInitializer.CompareSetGreaterEqual.SymbolInfo.FirstOrDefault()); + tctn.scope.AddSymbol(compiler_string_consts.sm_name, SystemLibrary.SystemLibInitializer.CompareSetLess.SymbolInfo.FirstOrDefault()); + tctn.scope.AddSymbol(compiler_string_consts.smeq_name, SystemLibrary.SystemLibInitializer.CompareSetLessEqual.SymbolInfo.FirstOrDefault()); + tctn.scope.AddSymbol(compiler_string_consts.eq_name, SystemLibrary.SystemLibInitializer.CompareSetEquals.SymbolInfo.FirstOrDefault()); + tctn.scope.AddSymbol(compiler_string_consts.noteq_name, SystemLibrary.SystemLibInitializer.CompareSetInEquals.SymbolInfo.FirstOrDefault()); + } + + private void CreateSpecialFields(common_unit_node psystem_unit) + { + List sil = psystem_unit.scope.Find(compiler_string_consts.IsConsoleApplicationVariableName); + if (sil != null && sil.FirstOrDefault().sym_info is namespace_variable) + { + namespace_variable_reference nvr = new namespace_variable_reference(sil.FirstOrDefault().sym_info as namespace_variable, null); + psystem_unit.IsConsoleApplicationVariableAssignExpr = make_assign_operator(nvr, psystem_unit.IsConsoleApplicationVariableValue, null); + } + } + + private void UpdateUnitDefinitionItemForUnit(common_unit_node unit) + { + if (!from_pabc_dll) + { + SystemLibrary.SystemLibInitializer.read_procedure = new SystemLibrary.UnitDefinitionItem(unit, compiler_string_consts.read_procedure_name); + SystemLibrary.SystemLibInitializer.readln_procedure = new SystemLibrary.UnitDefinitionItem(unit, compiler_string_consts.readln_procedure_name); + } + else + { + //SystemLibrary.SystemLibInitializer.read_procedure = new SystemLibrary.UnitDefinitionItem(unit, compiler_string_consts.read_procedure_name); + //SystemLibrary.SystemLibInitializer.readln_procedure = new SystemLibrary.UnitDefinitionItem(unit, compiler_string_consts.readln_procedure_name); + } + } + + public void reset() + { + _system_unit = null; + SystemLibrary.SystemLibrary.system_unit = null; + //SystemLibrary.SystemLibrary.Reset(); + SystemUnitAssigned = false; + _compiled_unit = null; + _referenced_units = null; + current_document = null; + using_list.clear(); + //_referenced_units.clear(); + ret.reset(); + motivation_keeper.reset(); + context.reset(); + convertion_data_and_alghoritms.reset(); + //compiled_type_node.compiled_types.Clear(); + internal_reset(); + release_system_module(); + WaitedRefTypes.Clear(); + set_intls.Clear(); + NetHelper.NetHelper.reset(); + if (ErrorsList != null) + ErrorsList.Clear(); + from_pabc_dll = false; + in_interface_part = false; + compiled_type_node[] ctns = new compiled_type_node[compiled_type_node.compiled_types.Values.Count]; + compiled_type_node.compiled_types.Values.CopyTo(ctns, 0); + null_type_node.reset(); + foreach (compiled_type_node ctn in ctns) + { + ctn.reinit_scope(); + ctn.clear_generated_names(); + ctn.clear_generated_intersections(); + } + } + + public PascalABCCompiler.Errors.SyntaxError parser_error + { + get + { + return convertion_data_and_alghoritms.parser_error; + } + set + { + convertion_data_and_alghoritms.parser_error = value; + } + } + public System.Collections.Hashtable bad_nodes_in_syntax_tree + { + get + { + return convertion_data_and_alghoritms.bad_nodes_in_syntax_tree; + } + set + { + convertion_data_and_alghoritms.bad_nodes_in_syntax_tree = value; + } + + } + + public PascalABCCompiler.TreeRealization.document CurrentDocument + { + get + { + return current_document; + } + } + + public SymbolTable.TreeConverterSymbolTable SymbolTable + { + get + { + return convertion_data_and_alghoritms.symbol_table; + } + } + + public location get_location(SyntaxTree.syntax_tree_node tn) + { + var tnn = tn; + /*while (tnn.source_context == null && tnn.Parent != null) + { + tnn = tnn.Parent; + }*/ + var tns = tnn.source_context; + + if (tns == null) + { + return null; + } + document d = current_document; + if (tns.FileName != null && (d == null || d.file_name != tns.FileName)) + d = new document(tns.FileName); + return new location(tns.begin_position.line_num, tns.begin_position.column_num, + tns.end_position.line_num, tns.end_position.column_num, d); + } + public location get_right_location(SyntaxTree.syntax_tree_node tn) + { + if (tn.source_context == null) + { + return null; + } + return new location(tn.source_context.end_position.line_num, tn.source_context.end_position.column_num, + tn.source_context.end_position.line_num, tn.source_context.end_position.column_num, current_document); + } + + public location get_location_with_check(SyntaxTree.syntax_tree_node tn) + { + if (tn == null || tn.source_context == null) + { + return null; + } + document d = current_document; + if (tn.source_context.FileName != null) + d = new document(tn.source_context.FileName); + return new location(tn.source_context.begin_position.line_num, tn.source_context.begin_position.column_num, + tn.source_context.end_position.line_num, tn.source_context.end_position.column_num, d); + } + + public common_unit_node compiled_unit + { + get + { + return _compiled_unit; + } + //TODO: Нужен ли set? + set + { + _compiled_unit = value; + } + } + + public PascalABCCompiler.TreeRealization.unit_node_list referenced_units + { + get + { + return _referenced_units; + } + set + { + _referenced_units = value; + } + } + + //TODO: Может вынести всю работу с returner-ами в convertion_data_and_alghoritms? + //Методы returner-а. + //Запрос на построение и получение конвертированного поддерева. + //Нежесткая проверка существования узла. + private statement_node convert_weak(SyntaxTree.statement st) + { + if (st == null) + { + return null; + } + + convertion_data_and_alghoritms.check_node_parser_error(st); + + //st = prepare_statement(st); + + statement_node sn = ret.visit(st); + //sn.loc=get_location(st); + return sn; + } + + private expression_node convert_weak(SyntaxTree.expression expr) + { + if (expr == null) + { + return null; + } + + convertion_data_and_alghoritms.check_node_parser_error(expr); + + //Посмотреть, может вызвать ошибку + //ssyy + motivation_keeper.reset(); + //\ssyy + + expression_node en = ret.visit(expr); + //en.loc=get_location(expr); + return en; + } + + private type_node convert_weak(SyntaxTree.type_definition type_def) + { + if (type_def == null) + { + return null; + } + + convertion_data_and_alghoritms.check_node_parser_error(type_def); + + return ret.visit(type_def); + } + + //Жесткая проверка существования узла. Проверка будет осуществлятся только в DEBUG версии. + //Будем верить, что в RELEAS-е все будет работать правильно. + private semantic_node convert_semantic_strong(SyntaxTree.syntax_tree_node tn) + { +#if (DEBUG) + if (tn == null) + { + throw new CompilerInternalError("This syntax tree node can not be null."); + } +#endif + + convertion_data_and_alghoritms.check_node_parser_error(tn); + motivation_keeper.set_motivation_to_expect_semantic_node(); + return ret.visit(tn); + } + + internal statement_node convert_strong(SyntaxTree.statement st) + { +#if (DEBUG) + if (st == null) + { + throw new CompilerInternalError("This syntax tree node can not be null."); + } +#endif + + #region MikhailoMMX, обработка критических секций OpenMP + bool isCritical = false; + SyntaxTree.statement st_orig = st; + if (OpenMP.LocksFound) + if (DirectivesToNodesLinks.ContainsKey(st) && OpenMP.IsCriticalDirective(DirectivesToNodesLinks[st])) + { + //если перед узлом есть директива omp critical + isCritical = true; + OpenMP.TryConvertCritical(ref st, this, DirectivesToNodesLinks[st]); + OpenMP.DisableDirective(st_orig, DirectivesToNodesLinks); + } + #endregion + + convertion_data_and_alghoritms.check_node_parser_error(st); + + //st = prepare_statement(st); + statement_node sn = null; + //try + { + sn = ret.visit(st); + // SSM 19/01/17 закомментировал две следующие строчки + //if (sn == null) + // sn = new empty_statement(null); + } + /*catch (PascalABCCompiler.Errors.Error e) + { + if (ThrowCompilationError) + throw e; + else + { + ErrorsList.Add(e); + return new empty_statement(null); + } + } + catch (Exception e) + { + if (ThrowCompilationError) + throw e; + else + return new empty_statement(null); + }*/ + //sn.loc=get_location(st); + + #region MikhailoMMX, обработка критических секций OpenMP + if (isCritical) + OpenMP.EnableDirective(st_orig, DirectivesToNodesLinks); + #endregion + + return sn; + } + + internal expression_node convert_strong(SyntaxTree.expression expr) + { +#if DEBUG + //var s = expr + "\n"; + //System.IO.File.AppendAllText("d:\\bb17.txt", s); +#endif + +#if (DEBUG) + if (expr == null) + { + throw new CompilerInternalError("This syntax tree node can not be null."); + } +#endif + //if (expr.semantic_ex != null) // SSM 3.1.17 - возвращаем кешированное значение + // return expr.semantic_ex as expression_node; + + convertion_data_and_alghoritms.check_node_parser_error(expr); + + //Посмотреть, может вызвать ошибку + //ssyy + motivation_keeper.reset(); // Это можно закомментировать - все тесты проходят SSM 2/1/17 + //\ssyy + expression_node en = ret.visit(expr); + + //if (lambdaProcessingState == LambdaProcessingState.FinishPhase) + // expr.semantic_ex = en; // SSM 3.1.17 кешируем для последующего обращения + + if (en == null) + AddError(get_location(expr), "EXPRESSION_EXPECTED"); + //en.loc=get_location(expr); + + return en; + } + + internal type_node convert_strong(SyntaxTree.type_definition type_def) + { +#if (DEBUG) + if (type_def == null) + { + throw new CompilerInternalError("This syntax tree node can not be null."); + } +#endif + + convertion_data_and_alghoritms.check_node_parser_error(type_def); + + type_node tn; + SyntaxTree.function_header fh = (type_def as SyntaxTree.function_header); + if (fh != null) + { + tn = convert_function_type(fh, get_location(type_def), context.get_delegate_type_name(), null); + return tn; + } + else + { + SyntaxTree.procedure_header ph = (type_def as SyntaxTree.procedure_header); + if (ph != null) + { + tn = convert_function_type(ph, get_location(type_def), context.get_delegate_type_name(), null); + return tn; + } + } + if (is_direct_type_decl && !(type_def is SyntaxTree.ref_type)) is_direct_type_decl = false; + return ret.visit(type_def); + } + + public addressed_expression convert_address_strong(SyntaxTree.addressed_value av) + { +#if (DEBUG) + if (av == null) + { + throw new CompilerInternalError("This syntax tree node can not be null."); + } +#endif + + convertion_data_and_alghoritms.check_node_parser_error(av); + + motivation_keeper.set_motivation_to_expect_address(); + addressed_expression ae = ret.visit(av); + //ae.loc=get_location(av); + return ae; + } + + //Возвращение конвертированного поддерева. + private void return_value(statement_node stat) + { + ret.return_value(stat); + } + + private void return_value(expression_node expr) + { + ret.return_value(expr); + } + + private void return_value(type_node tn) + { + ret.return_value(tn); + } + + private void return_addressed_value(addressed_expression ae) + { + ret.return_value(ae); + } + + private void return_semantic_value(semantic_node se) + { + ret.return_value(se); + } + + public void weak_node_test_and_visit(SyntaxTree.syntax_tree_node tn) + { + if (tn != null) + { + convertion_data_and_alghoritms.check_node_parser_error(tn); + tn.visit(this); + } + } + + public void hard_node_test_and_visit(SyntaxTree.syntax_tree_node tn) + { +#if (DEBUG) +// try +// { + if (tn == null) + { + throw new CompilerInternalError("This node can not be null"); + } +#endif + convertion_data_and_alghoritms.check_node_parser_error(tn); + if (is_direct_type_decl && !(tn is SyntaxTree.ref_type)) + is_direct_type_decl = false; + tn.visit(this); +/*#if (DEBUG) + } + catch (Exception e) + { + if (tn != null) + throw new Exception("" + tn.source_context.ToString() + System.Environment.NewLine + e.ToString()); + else throw e; + } +#endif*/ + } + + private void assign_doc_info(definition_node dn, SyntaxTree.syntax_tree_node stn) + { + string s = null; + if (docs != null && docs.TryGetValue(stn, out s) && !string.IsNullOrEmpty(s)) + { + dn.documentation = s; + } + return; + } + + //Последний параметер - выходной. Он слдержит список параметров с преобразованиями типов. + private function_node find_function(string name, location loc, PascalABCCompiler.TreeRealization.expressions_list parameters) + { + List sil = context.find(name); + if (sil == null) + { + AddError(new NoFunctionWithThisName(loc)); + } + if (sil.FirstOrDefault().sym_info.general_node_type != general_node_type.function_node) + { + AddError(new ThisIsNotFunctionName(loc)); + } + function_node fn = convertion_data_and_alghoritms.select_function(parameters, sil, loc); + return fn; + } + + //TODO: Обратить внимание на эту функцию. Ее вызовы не приводят к созданиям узлов преобразования типов. + private function_node find_function(string name, location loc, params expression_node[] exprs) + { + expressions_list exprs_list = new expressions_list(); + exprs_list.AddRange(exprs); + return find_function(name, loc, exprs_list); + } + + private expression_node find_operator(SyntaxTree.Operators ot, expression_node expr, location loc) + { + string name = name_reflector.get_name(ot); + //#if (DEBUG) + if (name == null) + { + if (ot == PascalABCCompiler.SyntaxTree.Operators.AddressOf) + { + if (expr.is_addressed == false) + { + AddError(expr.location, "CAN_NOT_GET_ADDRESS_FROM_EXPRESSION"); + } + expression_node res = new get_addr_node(expr, loc); + return res; + } + if (ot == PascalABCCompiler.SyntaxTree.Operators.Dereference) + { + } + throw new CompilerInternalError("Invalid operator name"); + } + //#endif + List sil = expr.type.find(name, context.CurrentScope); + if (sil == null || sil.FirstOrDefault().sym_info is wrapped_definition_node) + { + AddError(new OperatorCanNotBeAppliedToThisType(name, expr)); + } + + expressions_list pars = new expressions_list(); + pars.AddElement(expr); + bool tmp = ThrowCompilationError; + ThrowCompilationError = false; + function_node fn; + fn = convertion_data_and_alghoritms.select_function(pars, sil, loc); + ThrowCompilationError = tmp; + if (fn == null) + { + RemoveLastError(); + AddError(new OperatorCanNotBeAppliedToThisType(name, expr)); + } + expr = pars[0]; +#if (DEBUG) + convertion_data_and_alghoritms.check_operator(fn); +#endif + expression_node exp_node = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, expr); + return exp_node; + } + + private expression_node find_operator(SyntaxTree.Operators ot, expression_node left, expression_node right, location loc) + { + string name = name_reflector.get_name(ot); + return find_operator(name, left, right, loc); + } + + bool CheckExpressionType(expression_node expr) + { + if (expr.type == null) + { + AddError(expr.location, "TYPE_NOT_DEFINED"); + return false; + } + return true; + } + + internal bool one_way_operation(string name) + { + if (name == compiler_string_consts.plusassign_name) return true; + if (name == compiler_string_consts.minusassign_name) return true; + if (name == compiler_string_consts.multassign_name) return true; + if (name == compiler_string_consts.assign_name) return true; + if (name == compiler_string_consts.divassign_name) return true; + return false; + } + + public expression_node find_operator(string name, expression_node left, expression_node right, location loc, bool no_search_in_extension_methods = true) + { +#if (DEBUG) + if (name == null) + { + throw new CompilerInternalError("Invalid operator name"); + } +#endif + // Видимо, это сделано для присваивания, т.к. несимметрично. Но странно - f = nil должно возвращать boolean ! + if (right.semantic_node_type == semantic_node_type.null_const_node) + { + if ( !type_table.is_with_nil_allowed(left.type) && !left.type.IsPointer) + AddError(right.location, "NIL_WITH_VALUE_TYPES_NOT_ALLOWED"); + if (right.conversion_type == null) + right = null_const_node.get_const_node_with_type(left.type, (null_const_node)right); + } + + /*if (left.semantic_node_type == semantic_node_type.null_const_node) + { + if (!type_table.is_with_nil_allowed(right.type) && !right.type.IsPointer) + AddError(left.location, "NIL_WITH_VALUE_TYPES_NOT_ALLOWED"); + left = null_const_node.get_const_node_with_type(right.type, (null_const_node)left); + }*/ + + type_node left_type = left.type; + type_node right_type = right.type; + + if (left_type.semantic_node_type == semantic_node_type.delegated_method) + { + delegated_methods dm1 = (delegated_methods)left_type; + if (dm1.empty_param_method != null) + { + if (dm1.empty_param_method.simple_function_node.return_value_type != null) + { + left_type = dm1.empty_param_method.simple_function_node.return_value_type; + } + } + } + + if (right_type.semantic_node_type == semantic_node_type.delegated_method && !left_type.IsDelegate && left_type.semantic_node_type != semantic_node_type.delegated_method) + { + try_convert_typed_expression_to_function_call(ref right); + if (name != compiler_string_consts.plusassign_name && name != compiler_string_consts.minusassign_name) + try_convert_typed_expression_to_function_call(ref left); + + right_type = right.type; + } + if (right_type.semantic_node_type == semantic_node_type.delegated_method && name != compiler_string_consts.plusassign_name && name != compiler_string_consts.minusassign_name) + { + delegated_methods dm2 = (delegated_methods)right_type; + if (dm2.empty_param_method != null) + { + if (dm2.empty_param_method.simple_function_node.return_value_type != null) + { + right_type = dm2.empty_param_method.simple_function_node.return_value_type; + } + } + } + if (name == "+" && right_type == SystemLibrary.SystemLibrary.char_type && left_type != SystemLibrary.SystemLibrary.string_type) + no_search_in_extension_methods = false; + List sil = left_type.find_in_type(name, left_type.Scope, null, no_search_in_extension_methods); + int added_symbols = -1; + List sil2 = null; + if (left_type != right_type && !one_way_operation(name)) + { + //SymbolInfo si2 = right_type.find(name, context.CurrentScope); + if (sil != null) + sil = new List(sil); + if (name == "+" && right_type != SystemLibrary.SystemLibrary.string_type && left_type == SystemLibrary.SystemLibrary.char_type) + no_search_in_extension_methods = false; + sil2 = right_type.find_in_type(name, right_type.Scope, null, no_search_in_extension_methods); + + if ((sil != null) && (sil2 != null)) + { + //Важная проверка. Возможно один и тот же оператор с одними и теми же типами определен в двух разных классах. + //Возможно она занимает много времени, но, наверное, от нее нельзя отказаться. + List funcs = new List(); + foreach(SymbolInfo sic in sil) + { + if (sic.sym_info.general_node_type != general_node_type.function_node) + { + BasePCUReader.RestoreSymbols(sil, name); + } +#if (DEBUG) + if (sic.sym_info.general_node_type != general_node_type.function_node) + { + throw new CompilerInternalError("Expected operator."); + } +#endif + + function_node fn = (function_node)sic.sym_info; + if (convertion_data_and_alghoritms.is_exist_eq_method_in_list(fn, funcs) == null) + { + //break; + funcs.Add(fn); + } + } + //TODO: Разобраться с зацикливанием. + function_node_list fnl = new function_node_list(); + foreach(SymbolInfo sic in sil2) + { + if (sic.sym_info.general_node_type != general_node_type.function_node) + { + BasePCUReader.RestoreSymbols(sil2, name); + } +#if (DEBUG) + if (sic.sym_info.general_node_type != general_node_type.function_node) + { + throw new CompilerInternalError("Expected operator."); + } +#endif + fnl.AddElement(((function_node)(sic.sym_info))); + } + added_symbols = sil.Count() - 1; + foreach (function_node fnode in fnl) + { + function_node eq_func = convertion_data_and_alghoritms.find_eq_method_in_list(fnode, funcs); + if (eq_func != null) + { + //TODO: Проверить правильно ли это будет работать. + if (eq_func != fnode)//zachem eto nuzhno voobshe?? + { + basic_function_node bbfn1 = fnode as basic_function_node; + basic_function_node bbfn2 = eq_func as basic_function_node; + if ((bbfn1 != null) && (bbfn2 != null)) + { + if (bbfn1.basic_function_type != bbfn2.basic_function_type) + { + AddError(new TwoOperatorsCanBeCalled(eq_func, fnode, left, right)); + } + //sic = sic.Next; + continue; + } + else + { + if (left.type.type_special_kind == SemanticTree.type_special_kind.set_type && right.type.type_special_kind == SemanticTree.type_special_kind.set_type + || left.type.type_special_kind == SemanticTree.type_special_kind.set_type && right.type.type_special_kind == SemanticTree.type_special_kind.base_set_type + || left.type.type_special_kind == SemanticTree.type_special_kind.base_set_type && right.type.type_special_kind == SemanticTree.type_special_kind.set_type + || left.type.type_special_kind == SemanticTree.type_special_kind.base_set_type && right.type.type_special_kind == SemanticTree.type_special_kind.base_set_type + || left.type == SystemLibrary.SystemLibrary.string_type && right.type.type_special_kind == SemanticTree.type_special_kind.short_string + || right.type == SystemLibrary.SystemLibrary.string_type && left.type.type_special_kind == SemanticTree.type_special_kind.short_string + || left.type.type_special_kind == SemanticTree.type_special_kind.short_string && right.type.type_special_kind == SemanticTree.type_special_kind.short_string + || left.type.IsDelegate == right.type.IsDelegate) + { + //if (left.type.find_in_type(name) !=null) + } + else + AddError(new TwoOperatorsCanBeCalled(eq_func, fnode, left, right)); + } + } + } + sil.Add(new SymbolInfo(fnode)); + } + } + else + { + if (sil == null && sil2 != null) + { + sil = sil2; + } + } + } + //if (si == null) + { + if (left_type.semantic_node_type == semantic_node_type.delegated_method && right_type.semantic_node_type == semantic_node_type.delegated_method) + { + List saved_sil = sil; + List saved_sil2 = sil2; + if (!(left is typed_expression)) + AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc)); + base_function_call bfc = ((left as typed_expression).type as delegated_methods).proper_methods[0]; + left = convertion_data_and_alghoritms.explicit_convert_type(left, CreateDelegate(bfc.simple_function_node)); + sil = left.type.find_in_type(name); + if (!(right is typed_expression) && right.type is delegated_methods) + bfc = (right.type as delegated_methods).proper_methods[0]; + else + bfc = ((right as typed_expression).type as delegated_methods).proper_methods[0]; + right = convertion_data_and_alghoritms.explicit_convert_type(right, CreateDelegate(bfc.simple_function_node)); + sil2 = right.type.find_in_type(name); + if (saved_sil != null && sil != null) + { + sil.RemoveRange(1, sil.Count() - 1); + sil.AddRange(saved_sil); + } + else + saved_sil = sil; + if (saved_sil2 != null && sil2 != null) + { + sil2.RemoveRange(1, sil2.Count() - 1); + sil2.AddRange(saved_sil2); + } + else + saved_sil2 = sil2; + if (saved_sil == null) + { + if (!no_search_in_extension_methods) + AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc)); + else + return find_operator(name, left, right, loc, false); + } + + } + else if (left_type.semantic_node_type == semantic_node_type.delegated_method) + { + + } + else if (sil != null && left.semantic_node_type == semantic_node_type.delegated_method) + { + List local_sil = sil; + + } + else if (sil == null) + { + if (no_search_in_extension_methods) + return find_operator(name, left, right, loc, false); + else + { + if (right.type is undefined_type) + AddError(right.location, "CAN_NOT_DEDUCE_TYPE_{0}", ""); + else + AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc)); + } + + } + + } + + // После этой точки right_type и left_type не используются! + + expressions_list pars = null; + function_node fnsel = null; + if (sil != null) + { + foreach (SymbolInfo tmp_si in sil) + { + if (tmp_si.sym_info is wrapped_definition_node) + BasePCUReader.RestoreSymbols(sil, name); + } + } + pars = new expressions_list(); + pars.AddElement(left); + pars.AddElement(right); + bool tmp_throw_error = ThrowCompilationError; + ThrowCompilationError = !no_search_in_extension_methods; + + fnsel = convertion_data_and_alghoritms.select_function(pars, sil, loc); + if (!ThrowCompilationError && fnsel == null) + { + RemoveLastError(); + ThrowCompilationError = tmp_throw_error; + return find_operator(name, left, right, loc, false); + } + else + ThrowCompilationError = tmp_throw_error; + //function_node fnsel=convertion_data_and_alghoritms.select_function(pars,si,loc); + CheckSpecialFunctionCall(sil, pars,loc); + //TODO: А это зачем? Можно передать в create_simple_function_call pars. + left = pars[0]; + right = pars[1]; + if (fnsel == null) + { + AddError(new OperatorCanNotBeAppliedToThisTypes(name, left, right, loc)); + } + if (added_symbols != -1 && sil != null && added_symbols < sil.Count()) + sil.RemoveRange(added_symbols + 1, sil.Count() - 1 - added_symbols); + + if (SystemUnitAssigned && in_check_range_region() && name == compiler_string_consts.assign_name && is_range_checkable(left.type) && is_range_checkable(right.type)) + { + ordinal_type_interface oti = left.type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; + if (left.type != SystemLibrary.SystemLibrary.char_type && left.type != SystemLibrary.SystemLibrary.uint64_type && !(oti.lower_value is ulong_const_node)) + if(!(oti.lower_value is enum_const_node) && !(oti.lower_value is char_const_node)) + right = convertion_data_and_alghoritms.convert_type(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CheckRangeFunction.sym_info as common_namespace_function_node, null, convertion_data_and_alghoritms.convert_type(right,SystemLibrary.SystemLibrary.int64_type), convertion_data_and_alghoritms.convert_type(oti.lower_value,SystemLibrary.SystemLibrary.int64_type),convertion_data_and_alghoritms.convert_type(oti.upper_value,SystemLibrary.SystemLibrary.int64_type)),right.type); + else if (oti.lower_value is enum_const_node) + { + right = convertion_data_and_alghoritms.explicit_convert_type(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CheckRangeFunction.sym_info as common_namespace_function_node, null, convertion_data_and_alghoritms.explicit_convert_type(right,SystemLibrary.SystemLibrary.int64_type), + convertion_data_and_alghoritms.explicit_convert_type(oti.lower_value,SystemLibrary.SystemLibrary.int64_type),convertion_data_and_alghoritms.explicit_convert_type(oti.upper_value,SystemLibrary.SystemLibrary.int64_type)),right.type); + } + else if (oti.lower_value is char_const_node) + right = convertion_data_and_alghoritms.create_simple_function_call( + SystemLibrary.SystemLibInitializer.CheckCharRangeFunction.sym_info as common_namespace_function_node, + null, right, oti.lower_value,oti.upper_value + ); + } + expression_node exp_node = convertion_data_and_alghoritms.create_simple_function_call(fnsel, loc, left, right); + return exp_node; + } + + internal bool in_check_range_region() + { + return false; + } + + internal bool is_range_checkable(type_node tn) + { + ordinal_type_interface oti = tn.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; + if (oti != null && !tn.IsEnum && tn != SystemLibrary.SystemLibrary.bool_type) + return true; + return false; + } + + private base_function_call_list convert_functions_to_calls(expression_node obj, List fnl, location loc, bool is_static) + { + base_function_call_list ret = new base_function_call_list(); + foreach (function_node fnode in fnl) + { + base_function_call bfc = null; + switch (fnode.semantic_node_type) + { + case semantic_node_type.common_namespace_function_node: + { + common_namespace_function_node cmfn = fnode as common_namespace_function_node; + common_namespace_function_call cnfc = new common_namespace_function_call(cmfn, loc); + if (cmfn.ConnectedToType != null) + cnfc.parameters.AddElement(obj); + if (cmfn.is_generic_function && !cmfn.is_generic_function_instance && cmfn.ConnectedToType != null && cmfn.parameters.Count == 1) + { + expressions_list parameters = new expressions_list(); + parameters.AddElement(obj); + function_node inst = null; + try + { + inst = generic_convertions.DeduceFunction(cmfn, parameters, true, context, loc); + } + catch + { + continue; + } + cnfc = new common_namespace_function_call((common_namespace_function_node)inst, loc); + if (cmfn.ConnectedToType != null) + cnfc.parameters.AddElement(obj); + } + /*if (cmfn.parameters.Count >= 1 && cmfn.parameters[cmfn.parameters.Count - 1].is_params) + { + convertion_data_and_alghoritms.select_function(cnfc.parameters, new SymbolInfo(cmfn), loc); + + }*/ + bfc = cnfc; + break; + } + case semantic_node_type.basic_function_node: + { + //Может здесь стоит и выругаться, но я не буду пока этого делать. + break; + } + case semantic_node_type.common_in_function_function_node: + { + common_in_function_function_node ciffn = fnode as common_in_function_function_node; + int depth = convertion_data_and_alghoritms.symbol_table.GetRelativeScopeDepth(ciffn.scope, + context.top_function.scope); + common_in_function_function_call ciffc = new common_in_function_function_call(ciffn, depth, loc); + bfc = ciffc; + break; + } + case semantic_node_type.common_method_node: + { + common_method_node cmn = fnode as common_method_node; + //Если cmn конструктор - то плохо, но его не должно сюда попасть. + if (cmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + { + if (!is_static) + { + if (obj == null) + obj = GetCurrentObjectReference(cmn.cont_type.Scope, cmn, loc);//new this_node(context.converted_type, loc); + + common_method_call cmc = new common_method_call(cmn, obj, loc); + cmc.virtual_call = !inherited_ident_processing; + bfc = cmc; + } + //ssyy!!! Мне сложно понять предназначение данного кода, но, по-видимому, + //следует его переписать так. + else if (cmn.is_constructor) + { + if (cmn.parameters.Count == 0) + { + if (cmn.cont_type.IsAbstract) + AddError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", cmn.cont_type.name); + ret.clear(); + ret.AddElement(new common_constructor_call(cmn, loc)); + return ret; + } + } + } + else + { + if (is_static) + { + common_static_method_call csmc = new common_static_method_call(cmn, loc); + bfc = csmc; + } + } + break; + } + case semantic_node_type.compiled_function_node: + { + compiled_function_node cfn = fnode as compiled_function_node; + if (cfn.cont_type.Scope == null && cfn is compiled_function_node) + (cfn.cont_type as compiled_type_node).init_scope(); + + if (cfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + //ispravleno ibond + //if (is_static) + { + + if (cfn.is_generic_function && !cfn.is_generic_function_instance && cfn.ConnectedToType != null && cfn.parameters.Count == 1) + { + expressions_list parameters = new expressions_list(); + parameters.AddElement(obj); + function_node inst = null; + try + { + inst = generic_convertions.DeduceFunction(cfn, parameters, true, context, loc); + } + catch + { + continue; + } + if (inst is common_namespace_function_node) + bfc = new common_namespace_function_call((common_namespace_function_node)inst, loc); + else if (inst is compiled_function_node) + bfc = new compiled_static_method_call((compiled_function_node)inst, loc); + else + bfc = new compiled_static_method_call(cfn, loc); + } + else + { + compiled_static_method_call csmc = new compiled_static_method_call(cfn, loc); + bfc = csmc; + + } + if (cfn.ConnectedToType != null) + bfc.parameters.AddElement(obj); + } + } + else + { + if (!is_static) + { + if (obj == null) + obj = GetCurrentObjectReference(cfn.cont_type.Scope, cfn, loc);//new this_node(context.converted_type, loc); + compiled_function_call cfc = new compiled_function_call(cfn, obj, loc); + cfc.virtual_call = !inherited_ident_processing; + bfc = cfc; + } + } + break; + } + case semantic_node_type.compiled_constructor_node: + { + //Этот код мы вроде не должны вызывать, но если он все-же вызовется. + compiled_constructor_node ccn = fnode as compiled_constructor_node; + compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc); + bfc = ccc; + break; + } + default: + { + throw new CompilerInternalError("Undefined method type."); + } + } + if (bfc != null) + { + ret.AddElement(bfc); + } + } + return ret; + } + + private base_function_call_list create_possible_delegates_list(expression_node obj, List sil, location loc, bool is_static) + { + if (sil == null) + { + return new base_function_call_list(); + } + var fnl = new List(); + foreach(SymbolInfo si in sil) + { + function_node fn = si.sym_info as function_node; + if (si.sym_info is compiled_property_node) + { + fn = (si.sym_info as compiled_property_node).get_function; + } + else if (si.sym_info is common_property_node) + { + fn = (si.sym_info as common_property_node).get_function; + } + if (convertion_data_and_alghoritms.find_eq_method_in_list(fn, fnl) == null) + { + if (!(obj != null && fn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && !fn.is_extension_method)) + { + if (fn.is_extension_method) + { + if (obj != null && (fn.parameters[0].type == obj.type || type_table.compare_types(fn.parameters[0].type, obj.type) == type_compare.greater_type)) + fnl.Insert(0,fn); + else + fnl.Add(fn); + } + else + fnl.Add(fn); + } + } + else + { + + } + } + return convert_functions_to_calls(obj, fnl, loc, is_static); + } + + private base_function_call_list create_possible_delegates_list(expression_node obj, function_node func, location loc, bool is_static) + { + var fnl = new List(); + fnl.Add(func); + return convert_functions_to_calls(obj, fnl, loc, is_static); + } + + internal typed_expression make_delegate_wrapper(expression_node obj, List sil, location loc, bool is_static) + { + base_function_call_list fnl = create_possible_delegates_list(obj, sil, loc, is_static); + if (fnl.Count == 0) + { + if (is_static) + { + AddError(loc, "EXPECTED_STATIC_METHOD"); + } + else + { + if (sil != null && sil.Count != 0 && sil.First().sym_info is basic_function_node) + { + basic_function_node bfn = sil.First().sym_info as basic_function_node; + if (bfn.return_value_type != null) + AddError(loc, "USING_{0}_NOT_ALLOWED_IN_THIS_CONTEXT", bfn.name); + else + AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", bfn.name); + } + else + AddError(loc, "EXPECTED_NON_STATIC_METHOD"); + } + } + delegated_methods dm = new delegated_methods(); + dm.proper_methods.AddRange(fnl); + typed_expression te = new typed_expression(dm, loc); + return te; + } + + internal typed_expression make_delegate_wrapper(expression_node obj, function_node func, location loc, bool is_static) + { + base_function_call_list fnl = create_possible_delegates_list(obj, func, loc, is_static); + if (fnl.Count == 0) + { + if (is_static) + { + AddError(loc, "EXPECTED_STATIC_METHOD"); + } + else + { + AddError(loc, "EXPECTED_NON_STATIC_METHOD"); + } + } + delegated_methods dm = new delegated_methods(); + dm.proper_methods.AddRange(fnl); + typed_expression te = new typed_expression(dm, loc); + return te; + } + + private bool check_name_in_current_scope(string name) + { + + SymbolTable.Scope cscope = context.CurrentScope, name_scope = context.find_first(name).scope; + while (cscope is SymbolTable.BlockScope) + { + if (name_scope == cscope) + return true; + cscope = cscope.TopScope; + } + if (cscope is SymbolTable.UnitImplementationScope && name_scope is SymbolTable.UnitInterfaceScope) + return cscope.TopScope == name_scope; + return cscope == name_scope; + } + + void checkPolymorphicState(definition_node dn,location loc) + { + } + + private type_node find_type(string name, location loc) + { + definition_node di = context.check_name_node_type(name, loc, general_node_type.type_node); + type_node tn = (type_node)di; + return tn; + } + + //(ssyy) разбил + private type_node find_type(SyntaxTree.named_type_reference names, location loc) + { + definition_node di; + SyntaxTree.template_type_reference ttr = names as SyntaxTree.template_type_reference; + if (ttr != null) + { + di = ret.visit(names); + type_node tn = di as type_node; + if (tn == null) + { + AddError(loc, "TYPE_REFERENCE_EXPECTED"); + } + return tn; + } + List sil = context.find_definition_node(names, loc); + if (sil == null && attribute_converted) + { + names.names[names.names.Count-1].name += "Attribute"; + sil = context.find_definition_node(names, loc); + } + + if (sil != null && sil.FirstOrDefault().sym_info != null && sil.FirstOrDefault().sym_info.general_node_type == general_node_type.generic_indicator) + { + generic_indicator gi = sil.FirstOrDefault().sym_info as generic_indicator; + AddError(loc, "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", names.names[names.names.Count - 1].name, gi.generic.generic_params.Count); + } + if (sil == null || sil.FirstOrDefault().sym_info == null) + { + check_possible_generic_names(names, loc); + } + var lastname = names.names[names.names.Count - 1]; + syntax_tree_node l = lastname; + while (l.source_context == null && l.Parent != null) + l = l.Parent; + + lastname.source_context = l?.source_context; + di = context.check_name_node_type(lastname.name, sil?.FirstOrDefault(), get_location(lastname), general_node_type.type_node); + return (type_node)di; + } + + public void check_possible_generic_names(SyntaxTree.named_type_reference names, location loc) + { + string tmp = names.names[names.names.Count - 1].name; + int num; + string generic_name = compiler_string_consts.GetGenericTypeInformation(tmp, out num); + List counts; + bool found = NetHelper.NetHelper.generics_names.TryGetValue(generic_name.ToLower(), out counts); + if (found) + { + foreach (int k in counts) + { + names.names[names.names.Count - 1].name = generic_name + + compiler_string_consts.generic_params_infix + k.ToString(); + List sinfo = context.find_definition_node(names, loc); + if (sinfo != null) + { + names.names[names.names.Count - 1].name = tmp; + AddError(loc, "GENERIC_TYPE_{0}_NEEDS_{1}_GENERIC_PARAMETERS", generic_name, k); + break; + } + } + names.names[names.names.Count - 1].name = tmp; + } + } + + + public expression_node make_break_node(location call_location, params expression_node[] parameters) + { + if (parameters.Length != 0) + { + return null; + } + if (context.cycle_stack.Empty) + { + AddError(new BreakStatementWithoutComprehensiveCycle(call_location)); + } + statement_node sn = context.cycle_stack.top(); + switch (sn.semantic_node_type) + { + case semantic_node_type.while_node: + { + while_node wn = (while_node)sn; + return new while_break_node(wn, call_location); + } + case semantic_node_type.repeat_node: + { + repeat_node rn = (repeat_node)sn; + return new repeat_break_node(rn, call_location); + } + case semantic_node_type.for_node: + { + for_node fn = (for_node)sn; + return new for_break_node(fn, call_location); + } + case semantic_node_type.foreach_node: + { + foreach_node fn = (foreach_node)sn; + return new foreach_break_node(fn, call_location); + } + } + throw new CompilerInternalError("Undefined cycle type"); + } + + public expression_node make_continue_node(location call_location, params expression_node[] parameters) + { + if (parameters.Length != 0) + { + return null; + } + if (context.cycle_stack.Empty) + { + AddError(new ContinueStatementWithoutComprehensiveCycle(call_location)); + } + statement_node sn = context.cycle_stack.top(); + switch (sn.semantic_node_type) + { + case semantic_node_type.while_node: + { + while_node wn = (while_node)sn; + return new while_continue_node(wn, call_location); + } + case semantic_node_type.repeat_node: + { + repeat_node rn = (repeat_node)sn; + return new repeat_continue_node(rn, call_location); + } + case semantic_node_type.for_node: + { + for_node fn = (for_node)sn; + return new for_continue_node(fn, call_location); + } + case semantic_node_type.foreach_node: + { + foreach_node fn = (foreach_node)sn; + return new foreach_continue_node(fn, call_location); + } + } + throw new CompilerInternalError("Undefined cycle type"); + } + + public expression_node make_exit_node(location call_location, params expression_node[] parameters) + { + if (parameters.Length != 0) + { + return null; + } + if (!TreeConverter.SemanticRules.EnableExitProcedure) + AddError(new TreeConverter.UndefinedNameReference(TreeConverter.compiler_string_consts.exit_procedure_name, call_location)); + return new exit_procedure(call_location); + } + + public override void visit(SyntaxTree.inherited_message _inherited_message) + { + //throw new NotSupportedError(get_location(_inherited_message)); + var mot = motivation_keeper.motivation; + motivation_keeper.reset(); + + switch (mot) + { + case motivation.expression_evaluation: return_value(inherited_message_value_reciving(_inherited_message)); break; + //case motivation.symbol_info_reciving: return_symbol_value(blocks.find(_ident.name));break; + case motivation.address_receiving: + case motivation.semantic_node_reciving: AddError(get_location(_inherited_message), "CAN_NOT_ASSIGN_TO_LEFT_PART"); break; + } + } + + private expression_node current_catch_excep; + + public override void visit(SyntaxTree.try_stmt _try_stmt) + { + context.enter_code_block_without_bind(); + context.enter_exception_handlers(); + statement_node try_statements = convert_strong(_try_stmt.stmt_list); + context.leave_code_block(); + location loc = get_location(_try_stmt); + exception_filters_list efl = new exception_filters_list(); + SyntaxTree.try_handler_except try_hand_except = _try_stmt.handler as SyntaxTree.try_handler_except; + if (try_hand_except != null) + { + if (try_hand_except.except_block.handlers != null) + { + int hand_count = try_hand_except.except_block.handlers.handlers.Count; + for (int i = 0; i < hand_count; i++) + { + SyntaxTree.exception_handler eh = try_hand_except.except_block.handlers.handlers[i]; + type_node filter_type = convert_strong(eh.type_name); + if (!SemanticRules.GenerateNativeCode && !(filter_type.is_generic_parameter || + filter_type == SystemLibrary.SystemLibrary.exception_base_type || + type_table.is_derived(SystemLibrary.SystemLibrary.exception_base_type, filter_type))) + { + AddError(get_location(eh.type_name), "EXCEPTION_TYPE_MUST_BE_SYSTEM_EXCEPTION_OR_DERIVED_FROM_EXCEPTION"); + } + current_catch_excep = new int_const_node(2,null);//create_constructor_call(filter_type, new expressions_list(), null); + local_block_variable_reference lvr = null; + statements_list sl = new statements_list(get_location(eh.statements)); + convertion_data_and_alghoritms.statement_list_stack_push(sl); + context.enter_code_block_without_bind(); + if (eh.variable != null) + { + local_block_variable lbv = context.add_var_definition(eh.variable.name, get_location(eh.variable), filter_type, SemanticTree.polymorphic_state.ps_common, true) as local_block_variable; + lvr = new local_block_variable_reference(lbv, lbv.loc); + } + statement_node stm = convert_strong(eh.statements); + context.leave_code_block(); + sl = convertion_data_and_alghoritms.statement_list_stack.pop(); + if (sl.statements.Count > 0 || sl.local_variables.Count > 0) + { + sl.statements.AddElement(stm); + stm = sl; + } + + exception_filter ef = new exception_filter(filter_type, lvr, stm, get_location(eh)); + efl.AddElement(ef); + current_catch_excep = null; + } + } + else + { + context.enter_code_block_without_bind(); + exception_filter ef = new exception_filter(null, null, convert_strong(try_hand_except.except_block.stmt_list), get_location(try_hand_except.except_block.stmt_list)); + context.leave_code_block(); + efl.AddElement(ef); + } + if (try_hand_except.except_block.else_stmt_list != null) + { + context.enter_code_block_without_bind(); + statement_node else_stm = convert_strong(try_hand_except.except_block.else_stmt_list); + context.leave_code_block(); + type_node ftype = SystemLibrary.SystemLibrary.object_type; + exception_filter else_ef = new exception_filter(ftype, null, else_stm, else_stm.location); + efl.AddElement(else_ef); + } + } + else + { + type_node filter_type = compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.ExceptionName)); + expression_node current_catch_excep = create_constructor_call(filter_type, new expressions_list(), null); + local_block_variable_reference lvr = null; + local_block_variable tmp_var = context.add_var_definition(context.BuildName("$try_temp" + UniqueNumStr()), null, SystemLibrary.SystemLibrary.bool_type, null) as local_block_variable; + statements_list stm = new statements_list(null); + SyntaxTree.try_handler_finally try_hndlr_finally = _try_stmt.handler as SyntaxTree.try_handler_finally; + context.enter_code_block_without_bind(); + statement_node finally_stmt = convert_strong(try_hndlr_finally.stmt_list); + context.leave_code_block(); + stm.statements.AddElement(finally_stmt); + + basic_function_call bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,null); + bfc.parameters.AddElement(new local_block_variable_reference(tmp_var,null)); + stm.statements.AddElement(new if_node(bfc,new rethrow_statement_node(null),null,null)); + exception_filter ef = new exception_filter(filter_type, lvr, stm, null); + //efl.AddElement(ef); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,null); + bfc.parameters.AddElement(new local_block_variable_reference(tmp_var,null)); + bfc.parameters.AddElement(new bool_const_node(true,null)); + + //(try_statements as statements_list).statements.AddElement(bfc); + //(try_statements as statements_list).statements.AddElement(new throw_statement_node(current_catch_excep,null)); + return_value(new try_block(try_statements, finally_stmt, efl, loc)); + context.leave_exception_handlers(); + return; + } + statement_node finally_st = null; + SyntaxTree.try_handler_finally try_handler_finally = _try_stmt.handler as SyntaxTree.try_handler_finally; + if (try_handler_finally != null) + { + context.enter_code_block_without_bind(); + finally_st = convert_strong(try_handler_finally.stmt_list); + context.leave_code_block(); + } + try_block tb = new try_block(try_statements, finally_st, efl, loc); + context.leave_exception_handlers(); + return_value(tb); + } + + public override void visit(SyntaxTree.try_handler_except _try_handler_except) + { + throw new NotSupportedError(get_location(_try_handler_except)); + } + + public override void visit(SyntaxTree.try_handler_finally _try_handler_finally) + { + throw new NotSupportedError(get_location(_try_handler_finally)); + } + + public override void visit(SyntaxTree.try_handler _try_handler) + { + throw new NotSupportedError(get_location(_try_handler)); + } + + public override void visit(SyntaxTree.exception_block _exception_block) + { + throw new NotSupportedError(get_location(_exception_block)); + } + + public override void visit(SyntaxTree.exception_handler_list _exception_handler_list) + { + throw new NotSupportedError(get_location(_exception_handler_list)); + } + + public override void visit(SyntaxTree.exception_ident _exception_ident) + { + throw new NotSupportedError(get_location(_exception_ident)); + } + + public override void visit(SyntaxTree.exception_handler _exception_handler) + { + throw new NotSupportedError(get_location(_exception_handler)); + } + + public override void visit(SyntaxTree.known_type_ident _known_type_ident) + { + if (_known_type_ident.type == PascalABCCompiler.SyntaxTree.known_type.string_type) + { + var mot = motivation_keeper.motivation; + motivation_keeper.reset(); + switch (mot) + { + case motivation.address_receiving: return_value(SystemLibrary.SystemLibrary.string_type); break; + case motivation.expression_evaluation: return_value(SystemLibrary.SystemLibrary.string_type); break; + //case motivation.symbol_info_reciving: return_symbol_value(blocks.find(_ident.name));break; + case motivation.semantic_node_reciving: return_semantic_value(SystemLibrary.SystemLibrary.string_type); break; + } + + return; + } + //throw new NotSupportedError(get_location(_known_type_ident)); + } + + public override void visit(SyntaxTree.file_type _file_type) + { + if (_file_type.file_of_type != null) + { + //Типизированый файл + type_node el_type = convert_strong(_file_type.file_of_type); + check_for_type_allowed(el_type,get_location(_file_type.file_of_type)); + check_using_static_class(el_type, get_location(_file_type.file_of_type)); + //if (el_type == SystemLibrary.SystemLibrary.void_type) + // ErrorsList.Add(new VoidNotValid(get_location(_file_type.file_of_type))); + /*if (el_type == SystemLibrary.SystemLibInitializer.TextFileType.sym_info) + { + //Это текстовый файл!!! + return_value(el_type); + return; + }*/ + if (SystemLibrary.SystemLibInitializer.TypedFileType == null || SystemLibrary.SystemLibInitializer.TypedFileInitProcedure == null) + AddError(new NotSupportedError(get_location(_file_type))); + if (!CanUseThisTypeForTypedFiles(el_type)) + AddError(get_location(_file_type.file_of_type), "INVALID_ELEMENT_TYPE_FOR_TYPED_FILE", el_type); + return_value(context.create_typed_file_type(el_type, get_location(_file_type))); + } + else + { + //Бинарнай файл + if (SystemLibrary.SystemLibInitializer.BinaryFileType == null) + AddError(new NotSupportedError(get_location(_file_type))); + ((type_node)SystemLibrary.SystemLibInitializer.BinaryFileType.sym_info).type_special_kind = SemanticTree.type_special_kind.binary_file; + return_value((type_node)SystemLibrary.SystemLibInitializer.BinaryFileType.sym_info); + } + } + + private bool CanUseThisTypeForFiles (type_node el_type, bool allow_strings) + { + if (el_type.is_generic_parameter) + { + if (SemanticRules.AllowGenericParametersForFiles) + { + if (allow_strings) + get_type_abilities(el_type).useful_for_binary_files = true; + else + get_type_abilities(el_type).useful_for_typed_files = true; + return true; + } + else + { + return false; + } + } + if (el_type.type_special_kind == SemanticTree.type_special_kind.short_string) + return true; + if (el_type.type_special_kind == SemanticTree.type_special_kind.set_type) + { + if (el_type.element_type == SystemLibrary.SystemLibrary.byte_type || el_type.element_type == SystemLibrary.SystemLibrary.sbyte_type + || el_type.element_type == SystemLibrary.SystemLibrary.bool_type || el_type.element_type.IsEnum) return true; + else if (el_type.element_type.type_special_kind == SemanticTree.type_special_kind.diap_type) + { + if (el_type.element_type.base_type == SystemLibrary.SystemLibrary.byte_type || el_type.element_type.base_type == SystemLibrary.SystemLibrary.sbyte_type + || el_type.element_type.base_type == SystemLibrary.SystemLibrary.bool_type || el_type.element_type.base_type.IsEnum) return true; + if (el_type.element_type.base_type == SystemLibrary.SystemLibrary.integer_type) + { + ordinal_type_interface oti = el_type.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; + if (((oti.upper_value as int_const_node).constant_value-(oti.lower_value as int_const_node).constant_value) <= 256) + return true; + } + + return false; + } + return false; + } + if (el_type.is_value) + { + generic_instance_type_node gitn = el_type as generic_instance_type_node; + if (gitn != null) + { + List ftypes = gitn.all_field_types; + foreach (type_node ftype in ftypes) + { + if (!CanUseThisTypeForFiles(ftype, allow_strings)) + return false; + } + return true; + } + if (SystemLibrary.SystemLibrary.CanUseThisTypeForTypedFiles(el_type)) + return true; + if (el_type is common_type_node) + { + if (el_type as common_type_node == context.converted_type || + (el_type.original_generic != null && el_type.original_generic == context.converted_type)) + return false; + common_type_node ctn = el_type as common_type_node; + foreach (class_field cf in ctn.fields) + if (!cf.IsStatic) + if (cf.type.type_special_kind != SemanticTree.type_special_kind.short_string && !CanUseThisTypeForFiles(cf.type, allow_strings)) + return false; + return true; + } + if (el_type is compiled_type_node) + { + compiled_type_node ctn = el_type as compiled_type_node; + if (!ctn.compiled_type.IsLayoutSequential) + return false; + System.Reflection.FieldInfo[] fields = ctn.compiled_type.GetFields(); + foreach (System.Reflection.FieldInfo fi in fields) + if (!fi.IsStatic) + if (!CanUseThisTypeForFiles(compiled_type_node.get_type_node(fi.FieldType), allow_strings)) + return false; + return true; + } + } + if (IsBoundedArray(el_type)) + { + //это обычный массив + bounded_array_interface bai = (bounded_array_interface)el_type.get_internal_interface(internal_interface_kind.bounded_array_interface); + return CanUseThisTypeForFiles(bai.element_type, allow_strings); + } + if (allow_strings && el_type == SystemLibrary.SystemLibrary.string_type) + { + return true; + } + return false; + } + + private bool CanUseThisTypeForTypedFiles(type_node el_type) + { + if (el_type.type_special_kind == SemanticTree.type_special_kind.short_string) return true; + return CanUseThisTypeForFiles(el_type, false); + } + + private bool CanUseThisTypeForBinaryFiles(type_node el_type) + { + if (el_type == SystemLibrary.SystemLibrary.string_type || el_type is short_string_type_node) return true; + return CanUseThisTypeForFiles(el_type, true); + } + + internal List get_short_string_lens(type_node tn) + { + List lst = new List(); + if (tn.type_special_kind == SemanticTree.type_special_kind.short_string) + { + lst.Add((tn as short_string_type_node).Length); + } + if (tn is common_type_node) + { + common_type_node ctn = tn as common_type_node; + if (ctn.type_special_kind == SemanticTree.type_special_kind.array_wrapper) + { + lst.AddRange(get_short_string_lens(ctn.element_type)); + } + else if (ctn.type_special_kind == SemanticTree.type_special_kind.record) + { + foreach (class_field fld in ctn.fields) + lst.AddRange(get_short_string_lens(fld.type)); + } + } + return lst; + } + + internal int get_short_string_size(type_node tn) + { + if (tn.type_special_kind == SemanticTree.type_special_kind.short_string) + { + return (tn as short_string_type_node).Length+1; + } + if (tn is common_type_node) + { + common_type_node ctn = tn as common_type_node; + if (ctn.type_special_kind == SemanticTree.type_special_kind.array_wrapper) + { + int len = ((ctn.find_first_in_type(compiler_string_consts.internal_array_name).sym_info as class_field).type as simple_array).length; + return len*get_short_string_size(ctn.element_type); + } + else if (ctn.type_special_kind == SemanticTree.type_special_kind.record) + { + int off = 0; + foreach (class_field fld in ctn.fields) + off += get_short_string_size(fld.type); + return off; + } + return 0; + } + return 0; + } + + internal expression_node get_init_call_for_typed_file(var_definition_node vdn, type_node element_type) + { + location loc = (vdn.type as common_type_node).loc; + if (!SystemUnitAssigned) + AddError(new NotSupportedError(loc)); + //Когда заработает наследование конструкторов надо вставить это + /* + expression_node var_ref = create_variable_reference(vdn, loc); + expressions_list exl = new expressions_list(); + exl.AddElement(new typeof_operator(element_type, loc)); + base_function_call bfc = create_constructor_call(vdn.type, exl, loc); + expression_node expr = find_operator(compiler_string_consts.assign_name, var_ref, bfc, loc); + */ + + type_node tn = vdn.type; + vdn.type = SystemLibrary.SystemLibInitializer.TypedFileType.sym_info as type_node; + + expression_node var_ref = create_variable_reference(vdn, loc); + expressions_list exl = new expressions_list(); + exl.AddElement(var_ref); + exl.AddElement(new typeof_operator(element_type, loc)); + List lens = get_short_string_lens(element_type); + int sz = get_short_string_size(element_type); + if (sz > 0) + { + exl.AddElement(new int_const_node(get_short_string_size(element_type),null)); + for (int i=0; i 1) + fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.TypedSetInitProcedureWithBounds.SymbolInfo, loc); + else + fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.TypedSetInitProcedure.SymbolInfo, loc); + expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, null, exl.ToArray()); + + vdn.type = tn; + + return expr; + } + + internal expression_node get_init_call_for_set_as_constr(var_definition_node vdn, expression_node init_value) + { + location loc = (vdn.type as common_type_node).loc; + if (!SystemUnitAssigned) + AddError(new NotSupportedError(loc)); + //Когда заработает наследование конструкторов надо вставить это + /* + expression_node var_ref = create_variable_reference(vdn, loc); + expressions_list exl = new expressions_list(); + exl.AddElement(new typeof_operator(element_type, loc)); + base_function_call bfc = create_constructor_call(vdn.type, exl, loc); + expression_node expr = find_operator(compiler_string_consts.assign_name, var_ref, bfc, loc); + */ + + type_node tn = vdn.type; + vdn.type = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node; + + expression_node var_ref = create_variable_reference(vdn, loc); + expressions_list exl = new expressions_list(); + //exl.AddElement(var_ref); + //exl.AddElement(new typeof_operator(element_type, loc)); + if (tn.element_type == SystemLibrary.SystemLibrary.byte_type) + { + exl.AddElement(new byte_const_node(byte.MinValue,null)); + exl.AddElement(new byte_const_node(byte.MaxValue,null)); + } + else if (tn.element_type == SystemLibrary.SystemLibrary.sbyte_type) + { + exl.AddElement(new sbyte_const_node(sbyte.MinValue,null)); + exl.AddElement(new sbyte_const_node(sbyte.MaxValue,null)); + } + else if (tn.element_type == SystemLibrary.SystemLibrary.short_type) + { + exl.AddElement(new short_const_node(short.MinValue,null)); + exl.AddElement(new short_const_node(short.MaxValue,null)); + } + else if (tn.element_type == SystemLibrary.SystemLibrary.ushort_type) + { + exl.AddElement(new ushort_const_node(ushort.MinValue,null)); + exl.AddElement(new ushort_const_node(ushort.MaxValue,null)); + } + else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.diap_type || tn.element_type.type_special_kind == SemanticTree.type_special_kind.enum_kind) + { + ordinal_type_interface ii = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; + exl.AddElement(ii.lower_value); + exl.AddElement(ii.upper_value); + } + exl.AddElement(init_value); + function_node fn = null; + if (exl.Count > 1) + { + fn = convertion_data_and_alghoritms.select_function(exl, (SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node).find_in_type(compiler_string_consts.default_constructor_name), loc); + } + else + { + fn = convertion_data_and_alghoritms.select_function(exl, (SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node).find_in_type(compiler_string_consts.default_constructor_name), loc); + } + //expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, null, exl.ToArray()); + expression_node expr = create_static_method_call_with_params(fn, loc, tn, false, exl); + vdn.type = tn; + + return expr; + } + + internal expression_node get_init_call_for_short_string(var_definition_node vdn) + { + location loc = (vdn.type as short_string_type_node).loc; + + type_node tn = vdn.type; + //vdn.type = SystemLibrary.SystemLibInitializer.ShortStringType.TypeNode; + vdn.type = SystemLibrary.SystemLibrary.string_type; + int Length = (tn as short_string_type_node).Length; + + expression_node var_ref = create_variable_reference(vdn, loc); + expressions_list exl = new expressions_list(); + exl.AddElement(var_ref); + exl.AddElement(new int_const_node(Length, loc)); + expression_node expr = null; + //if (SystemLibrary.SystemLibInitializer.ShortStringTypeInitProcedure != null) + //convertion_data_and_alghoritms.create_full_function_call(exl, SystemLibrary.SystemLibInitializer.ShortStringTypeInitProcedure.SymbolInfo, null, context.converted_type, context.top_function, true); + + vdn.type = tn; + + return expr; + } + + + public override void visit(SyntaxTree.op_type_node _op_type_node) + { + throw new NotSupportedError(get_location(_op_type_node)); + } + + public override void visit(SyntaxTree.raise_stmt _raise_stmt) + { + location loc = get_location(_raise_stmt); + if (_raise_stmt.expr == null) + { + var st = _raise_stmt.Parent; + while (st != null && !(st is exception_block)) + { + st = st.Parent; + } + //if (current_catch_excep == null) + if (st == null) + AddError(loc, "RAISE_WITHOUT_PARAMETERS_MUST_BE_IN_CATCH_BLOCK"); + return_value(new rethrow_statement_node(loc)); + return; + } + expression_node en = convert_strong(_raise_stmt.expr); + if (en is typed_expression) en = convert_typed_expression_to_function_call(en as typed_expression); + if (!SemanticRules.GenerateNativeCode && (!(type_table.is_derived(SystemLibrary.SystemLibrary.exception_base_type, en.type))) && + (en.type != SystemLibrary.SystemLibrary.exception_base_type)) + { + AddError(loc, "EXCEPTION_TYPE_MUST_BE_SYSTEM_EXCEPTION_OR_DERIVED_FROM_EXCEPTION"); + } + if (_raise_stmt.address != null) + { + AddError(new NotSupportedError(get_location(_raise_stmt.address))); + } + return_value(new throw_statement_node(en, loc)); + } + + public override void visit(SyntaxTree.token_info _token_info) + { + throw new NotSupportedError(get_location(_token_info)); + } + + public override void visit(SyntaxTree.initfinal_part _initfinal_part) + { + } + + private bool is_format_allowed=false; + + public override void visit(SyntaxTree.format_expr _format_expr) + { + if (_format_expr.expr == null || _format_expr.format1 == null) + AddError(get_location(_format_expr), "BAD_CONSTRUCTED_FORMAT_EXPRESSION"); + //TODO: Добавить проверки. + if (!SemanticRules.AllowUseFormatExprAnywhere && !is_format_allowed) + AddError(get_location(_format_expr.expr), "FORMAT_EXPRESSION_CAN_USE_ONLY_IN_THESE_PROCEDURES"); + expression_node expr = convert_strong(_format_expr.expr); + if (expr is typed_expression) + expr = convert_typed_expression_to_function_call(expr as typed_expression); + expression_node par1 = convert_strong(_format_expr.format1); + par1 = convertion_data_and_alghoritms.convert_type(par1, SystemLibrary.SystemLibrary.integer_type); + expression_node par2 = convert_weak(_format_expr.format2); + if (par2 != null) + { + if (expr.type != SystemLibrary.SystemLibrary.double_type && expr.type != SystemLibrary.SystemLibrary.float_type) + { + AddError(expr.location, "REAL_TYPE_IN_DOUBLE_COLON_EXPRESSION_EXPECTED"); + } + par2 = convertion_data_and_alghoritms.convert_type(par2, SystemLibrary.SystemLibrary.integer_type); + } + expressions_list exl = new expressions_list(); + exl.AddElement(expr); + exl.AddElement(par1); + if (par2 != null) + { + exl.AddElement(par2); + } + location loc = get_location(_format_expr); + if (!SystemUnitAssigned) + AddError( new NotSupportedError(loc)); + function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.format_function.SymbolInfo, + loc); + expression_node ret = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, exl.ToArray()); + return_value(ret); + } + + internal bool inherited_ident_processing = false; + public override void visit(SyntaxTree.inherited_ident _inherited_ident) + { + inherited_ident_processing = true; + var mot = motivation_keeper.motivation; + motivation_keeper.reset(); + switch (mot) + { + case motivation.address_receiving: return_addressed_value(inherited_ident_address_reciving(_inherited_ident)); break; + case motivation.expression_evaluation: return_value(inherited_ident_value_reciving(_inherited_ident)); break; + //case motivation.symbol_info_reciving: return_symbol_value(blocks.find(_ident.name));break; + case motivation.semantic_node_reciving: return_semantic_value(inherited_ident_semantic_reciving(_inherited_ident)); break; + } + inherited_ident_processing = false; + return; + } + + public override void visit(SyntaxTree.property_parameter_list _property_parameter_list) + { + throw new NotSupportedError(get_location(_property_parameter_list)); + } + + public override void visit(SyntaxTree.property_parameter _property_parameter) + { + throw new NotSupportedError(get_location(_property_parameter)); + } + + public override void visit(SyntaxTree.property_interface _property_interface) + { + //throw new NotSupportedError(get_location(_property_interface)); + } + + public override void visit(SyntaxTree.property_array_default _property_array_default) + { + throw new NotSupportedError(get_location(_property_array_default)); + } + + public override void visit(SyntaxTree.record_type_parts _record_type_parts) + { + throw new NotSupportedError(get_location(_record_type_parts)); + } + + public override void visit(SyntaxTree.var_def_list_for_record _var_def_list) + { + throw new NotSupportedError(get_location(_var_def_list)); + } + + public override void visit(SyntaxTree.diapason_expr _diapason_expr) + { + throw new NotSupportedError(get_location(_diapason_expr)); + } + + public override void visit(SyntaxTree.case_variants _case_variants) + { + throw new NotSupportedError(get_location(_case_variants)); + } + + public override void visit(SyntaxTree.literal _literal) + { + throw new NotSupportedError(get_location(_literal)); + } + + public override void visit(SyntaxTree.array_of_const_type_definition _array_of_const_type_definition) + { + throw new NotSupportedError(get_location(_array_of_const_type_definition)); + } + + public override void visit(SyntaxTree.array_of_named_type_definition _array_of_named_type_definition) + { + throw new NotSupportedError(get_location(_array_of_named_type_definition)); + } + + public override void visit(SyntaxTree.proc_block _proc_block) + { + throw new NotSupportedError(get_location(_proc_block)); + } + + private statements_list get_statements_list(statement_node sn) + { + statements_list snl = sn as statements_list; + if (snl != null) + { + return snl; + } + snl = new statements_list(null); + snl.statements.AddElement(sn); + return snl; + } + + private statements_list add_first_statement(statement_node list, statement_node statement) + { + statements_list snl = get_statements_list(list); + snl.statements.AddElementFirst(statement); + return snl; + } + + private statements_list add_last_statement(statement_node list, statement_node statement) + { + statements_list snl = get_statements_list(list); + snl.statements.AddElement(statement); + return snl; + } + + public override void visit(SyntaxTree.block _block) + { + var tt = context.converting_block(); + List declarations_with_lambdas = new List(); + if (/*context.converting_block() != block_type.namespace_block && */_block.defs != null && _block.defs.defs != null) + { + foreach (var def in _block.defs.defs.Where(d => d is const_definition || + d is consts_definitions_list || + d is variable_definitions)) + { + var lambdaSearcher = new LambdaSearcher(def); + if (lambdaSearcher.CheckIfContainsLambdas()) + { + if (context.converting_block() != block_type.namespace_block || !(def is variable_definitions)) + AddError(new LambdasNotAllowedInDeclarationsSection(get_location(lambdaSearcher.FoundLambda))); // SSM 6.06.15 - Хочется убрать это. В разделе описаний лямбды нужны - пусть и без замыканий. Если внутри подпрограммы - не нужны, но Вы же запретили везде! + else + declarations_with_lambdas.Add(def as variable_definitions); + } + } + } + int lambda_init_index = 0; + foreach (variable_definitions vd in declarations_with_lambdas) + { + foreach (var_def_statement vds in vd.list) + { + var lambdaSearcher = new LambdaSearcher(vds); + if (lambdaSearcher.CheckIfContainsLambdas() && !(vds.inital_value is function_lambda_definition) && vds.inital_value != null) // SSM 27/10/17 + { + procedure_definition func = + new short_func_definition( + SyntaxTreeBuilder.BuildShortFuncDefinition(new formal_parameters(), new procedure_attributes_list(), new method_name("<>lambda_initializer" + lambda_init_index), null, vds.inital_value, null)); + + vds.inital_value = new method_call(new ident("<>lambda_initializer"+lambda_init_index), new expression_list()); + _block.defs.InsertBefore(vd, func); + lambda_init_index++; + } + } + } + if (context.converting_block() == block_type.function_block && context.converted_func_stack.size == 1) + { + if (_block.defs != null) + foreach (declaration decl in _block.defs.defs) + { + if (decl is procedure_definition) + { + context.has_nested_functions = true; + break; + } + } + } + weak_node_test_and_visit(_block.defs); + if (context.converting_block() == block_type.function_block && context.converted_func_stack.size == 1) + context.has_nested_functions = false; + //ssyy добавил генерацию вызова конструктора предка без параметров + if (context.converting_block() == block_type.function_block) + { + common_method_node cmn = context.top_function as common_method_node; + if (cmn != null && cmn.is_constructor && !(cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static)) + { + context.allow_inherited_ctor_call = true; + if (_block.program_code != null && _block.program_code.subnodes != null) + { + //(ssyy) Для записей конструктор предка не вызываем. + bool should_ctor_add = context.converted_type.is_class; + if (should_ctor_add) + { + if (_block.program_code.subnodes.Count > 0) + { + SyntaxTree.procedure_call pc = _block.program_code.subnodes[0] as SyntaxTree.procedure_call; + if (pc != null || _block.program_code.subnodes[0] is SyntaxTree.inherited_message) + { + //SyntaxTree.inherited_ident ii = pc.func_name as SyntaxTree.inherited_ident; + //SyntaxTree.method_call mc = pc.func_name as SyntaxTree.method_call; + //SyntaxTree.ident id = pc.func_name as SyntaxTree.ident; + //if (/*ii != null*/id != null || mc != null /*&& mc.dereferencing_value is SyntaxTree.inherited_ident*/) + { + //(ssyy) Не уверен, что следующий оператор необходим. + convertion_data_and_alghoritms.check_node_parser_error(_block.program_code); + var lambdaSearcher = new LambdaSearcher(_block.program_code.subnodes[0]); + if (!lambdaSearcher.CheckIfContainsLambdas()) + { + statement_node inh = convert_strong(_block.program_code.subnodes[0]); + + compiled_constructor_call c1 = inh as compiled_constructor_call; + if (c1 != null && !c1._new_obj_awaited) + { + should_ctor_add = false; + } + else + { + common_constructor_call c2 = inh as common_constructor_call; + if (c2 != null && !c2._new_obj_awaited) + { + should_ctor_add = false; + } + } + } + + } + } + } + } + if (should_ctor_add) + { + //Пытаемся добавить вызов .ctor() предка... + //Для начала проверим, есть ли у предка таковой. + bool not_found = true; + List sym = context.converted_type.base_type.find_in_type(compiler_string_consts.default_constructor_name, context.CurrentScope); + if (sym != null) + { + foreach (SymbolInfo sym_unit in sym) + { + if (!not_found) + break; + compiled_constructor_node ccn = sym_unit.sym_info as compiled_constructor_node; + if (ccn != null && ccn.parameters.Count == 0) + { + not_found = false; + } + else + { + common_method_node cnode = sym_unit.sym_info as common_method_node; + if (cnode != null && cnode.is_constructor && (cnode.parameters.Count == 0 || cnode.parameters[0].default_value != null)) + { + not_found = false; + } + } + } + } + if (not_found) + { + var l = get_location(_block.program_code); + if (l == null) + { + AddError(cmn.return_value_type.location, "IN_AUTOGENERATED_DEFAULT_CONSTRUCTOR_THE_DEFAULT_CONSTRUCTOR_OF_BASE_CLASS_CANNOT_BE_CALLED_BECAUSE_IS_ABSENT_OR_PRIVATE"); + } + //У предка нет конструктора по умолчанию + AddError(l, "INHERITED_CONSTRUCTOR_CALL_EXPECTED"); + } + else + { + //Генерируем вызов .ctor() предка + SyntaxTree.inherited_ident ii = new SyntaxTree.inherited_ident(); + ii.name = compiler_string_consts.default_constructor_name; + _block.program_code.subnodes.Insert(0, new SyntaxTree.procedure_call(ii)); + //context.allow_inherited_ctor_call = false; + } + } + } + } + } + //\ssyy + + //ssyy + if (context.converting_block() == block_type.namespace_block) + { + context.check_predefinition_defined(); + } + + if (lambdaProcessingState == LambdaProcessingState.None && _block.program_code != null) + { + var lambdaSearcher = new LambdaSearcher(_block.program_code); + var lambdaIsFound = lambdaSearcher.CheckIfContainsLambdas(); + + if ((context.converting_block() == block_type.function_block || + context.converting_block() == block_type.namespace_block) && + lambdaIsFound) + // TODO: Пока обрабатываются только блок функции и основной блок, необходимо обрабатывать случаи появлений лямбд в var_def_statement + { + if (context.converting_block() == block_type.function_block) + { + if (context.func_stack.top().functions_nodes_list.Count > 0) + { + AddError(new LambdasNotAllowedWhenNestedSubprogrammesAreUsed(get_location(lambdaSearcher.FoundLambda))); + } + } + + lambdaProcessingState = LambdaProcessingState.TypeInferencePhase; + visit_program_code(_block.program_code); + + // Очистили списки goto для меток перед следующим этапом - пока ничего не дало - закомментируем + foreach (var l in context._cmn.labels) + { + l.goto_statements.Clear(); + l.comprehensive_code_block = null; + } + if (context.func_stack.size > 0) + { + var fun = context.func_stack.top(); + foreach (var l in fun.label_nodes_list) + { + l.goto_statements.Clear(); + l.comprehensive_code_block = null; + } + } + + // Грубо - удаление мусора при разборе лямбд. Происходит исключение - заголовок разбирается, тело остается пустым - и из-за этого была ошибка #1270. + while (context._cmn.functions.Count > 0 && context._cmn.functions[context._cmn.functions.Count-1].function_code == null && context._cmn.functions[context._cmn.functions.Count - 1].name.StartsWith("<>lambda") && !context._cmn.functions[context._cmn.functions.Count - 1].name.StartsWith("<>lambda_initializer")) + { +#if DEBUG + //System.IO.File.AppendAllText("aa.txt", context._cmn.functions[context._cmn.functions.Count - 1].name+"\n"); +#endif + context._cmn.functions.remove_at(context._cmn.functions.Count - 1); + + } + + lambdaProcessingState = LambdaProcessingState.ClosuresProcessingPhase; + CapturedVariablesSubstitutionsManager.Substitute(this, _block.defs, _block.program_code); + + lambdaProcessingState = LambdaProcessingState.FinishPhase; + + context.code = visit_program_code(_block.program_code); + + lambdaProcessingState = LambdaProcessingState.None; + } + else + { + context.code = visit_program_code(_block.program_code); + } + } + else + { + context.code = visit_program_code(_block.program_code); + } + } + + private statement_node visit_program_code(statement_list program_code) + { + context.enter_code_block_with_bind(); + statement_node sn = convert_strong(program_code); + context.leave_code_block(); + + return sn; + } + + public override void visit(SyntaxTree.diap_expr _diap_expr) + { + throw new NotSupportedError(get_location(_diap_expr)); + } + internal SymbolTable.Scope[] build_referenced_units(unit_node_list referenced_units, bool try_get_system_module) + { + List used_units = new List(); + Dictionary assembly_references_dict = new Dictionary(); + for (int i = 0; i < referenced_units.Count; i++) + { + if (referenced_units[i] is dot_net_unit_node) + if (!assembly_references_dict.ContainsKey((referenced_units[i] as dot_net_unit_node).dotNetScope._assembly)) + assembly_references_dict.Add((referenced_units[i] as dot_net_unit_node).dotNetScope._assembly, referenced_units[i] as dot_net_unit_node); + } + dot_net_unit_node[] assembly_references = new dot_net_unit_node[assembly_references_dict.Values.Count]; + assembly_references_dict.Values.CopyTo(assembly_references, 0); + List def_scopes = new List(); + if (SemanticRules.AllowGlobalVisibilityForPABCDll) + { + for (int i = 0; i < assembly_references.Length; i++) + { + if (assembly_references[i].dotNetScope.entry_type != null) + def_scopes.Add(assembly_references[i].dotNetScope); + } + } + //used_units.Add(_system_unit.scope); + for (int i = 0; i < referenced_units.Count; i++) + { + if (!(referenced_units[i] is dot_net_unit_node)) + { + if (referenced_units[i] is namespace_unit_node) + { + namespace_unit_node nun = referenced_units[i] as namespace_unit_node; + for (int j = 0; j < assembly_references.Length; j++) + { + using_namespace_list unl = new using_namespace_list(); + unl.AddElement((referenced_units[i] as namespace_unit_node).namespace_name); + NetHelper.NetScope ns = new PascalABCCompiler.NetHelper.NetScope(unl, assembly_references[j].dotNetScope._assembly, SymbolTable); + used_units.Add(ns); + } + if (_compiled_unit != null) + _compiled_unit.used_namespaces.Add((referenced_units[i] as namespace_unit_node).namespace_name.namespace_name); + if (nun.scope != null) + used_units.Add(nun.scope); + } + else + { + common_unit_node cun = referenced_units[i] as common_unit_node; + if (cun != null) + { + if (try_get_system_module && cun.IsSystemUnit) + { + get_system_module(cun); + for (int j = 0; j < def_scopes.Count; j++) + { + used_units.Add(new PascalABCCompiler.NetHelper.NetScope(interface_using_list, def_scopes[j]._assembly, SymbolTable)); + } + } + used_units.Add(cun.scope); + } + else + { + throw new CompilerInternalError("Unexpected unit type."); + } + } + } + else + { + dot_net_unit_node dun = referenced_units[i] as dot_net_unit_node; + if (dun.dotNetScope.entry_type != null && dun.dotNetScope.entry_type.Name == "PABCRtl") + { + if (try_get_system_module) + { + from_pabc_dll = true; + get_system_module_from_dll(dun); + } + } + } + } + List fetched_used_units = new List(); + Dictionary assm_cache = new Dictionary(); + for (int i = 0; i < used_units.Count; i++) + { + PascalABCCompiler.NetHelper.NetScope net_scope = used_units[i] as PascalABCCompiler.NetHelper.NetScope; + if (net_scope != null) + { + PascalABCCompiler.NetHelper.NetScope existing_scope = null; + if (assm_cache.TryGetValue(net_scope.Assembly, out existing_scope)) + { + /*if (net_scope.used_namespaces) + { + foreach (using_namespace un in net_scope.used_namespaces) + { + if (un.namespace_name) + } + }*/ + existing_scope.used_namespaces.AddRange(net_scope.used_namespaces); + } + else + { + if (NetHelper.NetHelper.PABCSystemType == null || net_scope.Assembly != NetHelper.NetHelper.PABCSystemType.Assembly) + assm_cache.Add(net_scope.Assembly, net_scope); + fetched_used_units.Add(net_scope); + } + } + else + fetched_used_units.Add(used_units[i]); + } + used_units = fetched_used_units; + //Если компилими implementation то в начало кладем все что было в interface + for (int i = 0; i < assembly_references.Length; i++) + { + used_units.Add(new PascalABCCompiler.NetHelper.NetScope(interface_using_list, (assembly_references[i] as dot_net_unit_node).dotNetScope._assembly, SymbolTable)); + } + used_units.Add(_system_unit.scope); + + return used_units.ToArray(); + } + + + public void visit_implementation(SyntaxTree.unit_module _unit_module) + { + if (_unit_module.initialization_part != null) + { + var lambdaSearcher = new LambdaSearcher(_unit_module.initialization_part); + if (lambdaSearcher.CheckIfContainsLambdas()) + { + AddError(new LambdasNotAllowedInInitializationPartOfModule(get_location(lambdaSearcher.FoundLambda))); + } + } + + if (_unit_module.finalization_part != null) + { + var lambdaSearcher = new LambdaSearcher(_unit_module.finalization_part); + if (lambdaSearcher.CheckIfContainsLambdas()) + { + AddError(new LambdasNotAllowedInFinalizationPartOfModule(get_location(lambdaSearcher.FoundLambda))); + } + } + + //using_list.AddRange(implementation_using_list); + /*if (_unit_module.implementation_part != null) + { + weak_node_test_and_visit(_unit_module.implementation_part.using_namespaces); + }*/ + + SymbolTable.Scope[] used_units = build_referenced_units(referenced_units,false); + + _compiled_unit.implementation_scope = + convertion_data_and_alghoritms.symbol_table.CreateUnitImplementationScope(_compiled_unit.scope, used_units); + + location loc = null; + if (_unit_module.unit_name != null) + { + loc = get_location(_unit_module.unit_name); + } + + common_namespace_node cnsn = context.create_namespace(_unit_module.unit_name.idunit_name.name + compiler_string_consts.ImplementationSectionNamespaceName, + _compiled_unit, _compiled_unit.implementation_scope, loc); + + //cnsn.scope=_compiled_unit.implementation_scope; + + if (_unit_module.implementation_part != null) + { + hard_node_test_and_visit(_unit_module.implementation_part); + } + + //weak_node_test_and_visit(_unit_module.initialization_part); + context.enter_code_block_without_bind(); + + statement_node init_statements = convert_weak(_unit_module.initialization_part); + context.leave_code_block(); + common_namespace_function_node initialization_function = null; + if (init_statements != null) + { + context.check_labels(context.converted_namespace.labels); + //(ssyy) Блокируем поставленные метки, чтобы не допустить переход из finalization-секции + //context.block_defined_labels(context.converted_namespace.labels); + initialization_function = new common_namespace_function_node(compiler_string_consts.initialization_function_name, + null, init_statements.location, context.converted_namespace, convertion_data_and_alghoritms.symbol_table.CreateScope(context.converted_namespace.scope)); + initialization_function.function_code = init_statements; + cnsn.functions.AddElement(initialization_function); + _compiled_unit.main_function = initialization_function; + context.apply_special_local_vars(_compiled_unit.main_function); + } + + context.enter_code_block_without_bind(); + statement_node final_statements = convert_weak(_unit_module.finalization_part); + context.leave_code_block(); + common_namespace_function_node finalization_function = null; + if (final_statements != null) + { + context.check_labels(context.converted_namespace.labels); + finalization_function = new common_namespace_function_node(compiler_string_consts.finalization_function_name, + null, final_statements.location, context.converted_namespace, convertion_data_and_alghoritms.symbol_table.CreateScope(context.converted_namespace.scope)); + finalization_function.function_code = final_statements; + cnsn.functions.AddElement(finalization_function); + _compiled_unit.finalization_method = finalization_function; + context.apply_special_local_vars(_compiled_unit.finalization_method); + } + + context.check_all_name_unit_defined(_compiled_unit); + } + + public override void visit(SyntaxTree.implementation_node _implementation_node) + { + if (_implementation_node.implementation_definitions != null && _implementation_node.implementation_definitions.defs != null) + { + foreach (var def in _implementation_node.implementation_definitions.defs.Where(d => d is const_definition || + d is consts_definitions_list || + d is variable_definitions)) + { + var lambdaSearcher = new LambdaSearcher(def); + if (lambdaSearcher.CheckIfContainsLambdas()) + { + AddError(new LambdasNotAllowedInImplementationOfModuleInInit(get_location(lambdaSearcher.FoundLambda))); + } + } + } + + weak_node_test_and_visit(_implementation_node.implementation_definitions); + } + + bool in_interface_part = false; + + public override void visit(SyntaxTree.interface_node _interface_node) + { + if (_interface_node.interface_definitions != null && _interface_node.interface_definitions.defs != null) + { + foreach (var def in _interface_node.interface_definitions.defs.Where(d => d is const_definition || + d is consts_definitions_list || + d is variable_definitions)) + { + var lambdaSearcher = new LambdaSearcher(def); + if (lambdaSearcher.CheckIfContainsLambdas()) + { + AddError(new LambdasNotAllowedInInterfacePartOfModuleInInit(get_location(lambdaSearcher.FoundLambda))); + } + } + } + + weak_node_test_and_visit(_interface_node.interface_definitions); + } + + + public override void visit(SyntaxTree.typecast_node node) + { + + expression_node en = convert_strong(node.expr); + location loc = get_location(node); + type_node tp = convert_strong(node.type_def); + //ssyy + if (en.type.semantic_node_type == semantic_node_type.delegated_method) + { + try_convert_typed_expression_to_function_call(ref en); + } + //\ssyy + if (!SemanticRules.IsAsForPointers && (tp.IsPointer || en.type.IsPointer)) + { + if (node.cast_op == PascalABCCompiler.SyntaxTree.op_typecast.is_op) + AddError(loc, "OPERATOR_{0}_CAN_NOT_BE_APPLIED_TO_POINTER_TYPE", compiler_string_consts.is_name); + else + AddError(loc, "OPERATOR_{0}_CAN_NOT_BE_APPLIED_TO_POINTER_TYPE", compiler_string_consts.as_name); + } + else + if (!(type_table.is_derived(en.type, tp) || type_table.is_derived(tp, en.type) + || en.type == tp || en.type == SystemLibrary.SystemLibrary.object_type + || en.type.IsInterface || tp.IsInterface || tp.is_generic_parameter || en.type.is_generic_parameter) + ) + { + AddError(loc, "EXPECTED_DERIVED_CLASSES"); + } + if (en.type.IsSealed && tp.IsInterface && /*!en.type.ImplementingInterfaces.Contains(tp)*/ + !convertion_data_and_alghoritms.type_or_base_type_implements_interface(en.type,tp) + ) + { + AddError(loc, "CAN_NOT_CONVERT_TYPE_{0}_TO_INTERFACE_{1}", en.type.PrintableName, tp.PrintableName); + } + if (node.cast_op == PascalABCCompiler.SyntaxTree.op_typecast.is_op) + { + is_node isn = new is_node(en, tp, loc); + return_value(isn); + } + else + { + if (tp.is_generic_parameter && !tp.is_class && !(tp.base_type != null && tp.base_type.is_class) && !(tp.base_type != null && tp.base_type.original_generic != null && tp.base_type.original_generic.is_class)) + AddError(get_location(node.type_def), "OPERATOR_AS_CAN_NOT_BE_USED_WITH_GENERIC_PARAMETER_{0}_WITHOUT_CLASS_CONSTRAINT", tp.name); + if (tp.is_value_type) + AddError(get_location(node.type_def), "OPERATOR_AS_MUST_BE_USED_WITCH_A_REFERENCE_TYPE_VALUETYPE{0}", tp.PrintableName); + as_node asn = new as_node(en, tp, loc); + return_value(asn); + } + } + + public override void visit(SyntaxTree.inherited_method_call _inherited_method_call) + { + throw new NotSupportedError(get_location(_inherited_method_call)); + } + + public override void visit(SyntaxTree.destructor _destructor) + { + if (_destructor.name == null) + { + AddError(get_location(_destructor), "DESTRUCTOR_MUST_HAVE_NAME"); + } + if (context.converting_block() == block_type.type_block) + { + if (context.converted_type.IsInterface) + { + AddError(get_location(_destructor), "DESTRUCTOR_IN_INTERFACE"); + } + if (!context.converted_type.is_class) + { + AddError(get_location(_destructor), "DESTRUCTOR_NOT_IN_CLASS"); + } + } + else if (!(context.converting_block() == block_type.namespace_block && _destructor.name.class_name != null)) + { + AddError(get_location(_destructor), "DESTRUCTOR_NOT_IN_CLASS"); + } + if (_destructor.parameters != null && _destructor.parameters.params_list.Count > 0) + { + AddError(get_location(_destructor), "DESTRUCTOR_CANNOT_HAVE_PARAMETERS"); + } + visit_procedure_header(_destructor); + } + + //ssyy изменил этот метод из-за изменения концепции конструкторов + public override void visit(SyntaxTree.constructor _constructor) + { + if (context.converting_block() == block_type.type_block) + { + if (context.converted_type.IsInterface) + { + AddError(new ConstructorInInterface(get_location(_constructor))); + } + /*if (!context.converted_type.is_class) + { + throw new ConstructorNotInClass(get_location(_constructor)); + }*/ + } + else if (!(context.converting_block() == block_type.namespace_block && _constructor.name != null && _constructor.name.class_name != null)) + { + AddError(get_location(_constructor), "CONSTRUCTOR_NOT_IN_CLASS"); + } + + convertion_data_and_alghoritms.check_node_parser_error(_constructor.name); + + if (_constructor.name == null) + { + SyntaxTree.ident name = new SyntaxTree.ident(compiler_string_consts.default_constructor_name); + _constructor.name = new PascalABCCompiler.SyntaxTree.method_name(null, null, name, null); + _constructor.name.source_context = _constructor.name.meth_name.source_context = _constructor.source_context; + } + + if (_constructor.name.meth_name.name.ToLower() != compiler_string_consts.default_constructor_name) + AddError(get_location(_constructor.name), "CONSTRUCTOR_CAN_HAVE_ONLY_{0}_NAME", compiler_string_consts.default_constructor_name); + if ((_constructor.name.class_name == null) && (context.converting_block() != block_type.type_block)) + { + AddError(get_location(_constructor.name), "ONLY_CONSTRUCTOR_OF_TYPE_ALLOWED"); + } + + foreach (SyntaxTree.procedure_attribute att in _constructor.proc_attributes.proc_attributes) + { + if (att.attribute_type == SyntaxTree.proc_attribute.attr_virtual) + { + AddError(get_location(att), "CONSTRUCTOR_CAN_NOT_BE_VIRTUAL"); + } + else if (att.attribute_type == SyntaxTree.proc_attribute.attr_override) + { + AddError(get_location(att), "CONSTRUCTOR_CAN_NOT_BE_OVERRIDE"); + } + else if (att.attribute_type == SyntaxTree.proc_attribute.attr_abstract) + { + AddError(get_location(att), "CONSTRUCTOR_CANNOT_BE_ABSTRACT"); + } + } + if (_constructor.class_keyword) + { + SyntaxTree.procedure_attribute pa = new SyntaxTree.procedure_attribute(PascalABCCompiler.SyntaxTree.proc_attribute.attr_static); + pa.source_context = _constructor.source_context; + _constructor.proc_attributes.proc_attributes.Add(pa); + } + foreach (SyntaxTree.procedure_attribute att in _constructor.proc_attributes.proc_attributes) + { + if (att.attribute_type == SyntaxTree.proc_attribute.attr_static) + { + //Это статический конструктор + if (_constructor.parameters != null) + { + AddError(get_location(_constructor.name), "STATIC_CONSTRUCTOR_MUST_BE_PARAMETERLESS"); + } + _constructor.name.meth_name.name = compiler_string_consts.static_ctor_prefix + _constructor.name.meth_name.name; + visit_procedure_header(_constructor); + if (context.top_function != null) + { + (context.top_function as common_method_node).is_constructor = true; + (context.top_function as common_method_node).cont_type.static_constr = context.top_function as common_method_node; + } + return; + } + } + + if (context.converting_block() == block_type.type_block) + { + //Нужно для генерации унаследованных конструкторов + context.converted_type.has_user_defined_constructor = true; + + //Нужно для генерации конструктора по умолчанию + if (_constructor.parameters == null || _constructor.parameters.params_list[0].inital_value != null) + { + context.converted_type.has_default_constructor = true; + } + } + + visit_procedure_header(_constructor); + + if (context.top_function == null) + { + return; + } + common_method_node cmn = context.top_function as common_method_node; + + if (cmn == null) + { + throw new CompilerInternalError("Constructor is not common_method_node."); + } + + context.allow_inherited_ctor_call = true; + cmn.is_constructor = true; + cmn.return_value_type = context.converted_type; + } + + public override void visit(SyntaxTree.file_type_definition _file_type_definition) + { + throw new NotSupportedError(get_location(_file_type_definition)); + } + + public override void visit(SyntaxTree.nil_const _nil_const) + { + return_value(new null_const_node(null_type_node.get_type_node(), get_location(_nil_const))); + } + + public override void visit(SyntaxTree.class_predefinition _class_predefinition) + { + throw new NotSupportedError(get_location(_class_predefinition)); + } + + private bool statement_expected = false; + private bool procedure_wait = false; + + public override void visit(SyntaxTree.procedure_call _procedure_call) + { + procedure_wait = true; + SyntaxTree.method_call mc = null; + mc = _procedure_call.func_name as SyntaxTree.method_call; + if (mc == null) + { + SyntaxTree.ident id = _procedure_call.func_name as SyntaxTree.ident; + if (id != null) + { + mc = new SyntaxTree.method_call(); + mc.dereferencing_value = id; // дело в том, что это присваивание перенаправляет Parent на method_call, которого нет в синтаксическом дереве. + id.Parent = _procedure_call; // fix #891 вернули Parent назад + //DarkStar Add + //Добавил т.к. нужно для генерации отладочной инфы + mc.source_context = id.source_context; + } + else + { + SyntaxTree.addressed_value adrv = _procedure_call.func_name as SyntaxTree.addressed_value; + if (adrv != null) + { + mc = new SyntaxTree.method_call(); + mc.dereferencing_value = adrv; + adrv.Parent = _procedure_call; // fix #891 + //DarkStar Add + //Добавил т.к. нужно для генерации отладочной инфы + mc.source_context = adrv.source_context; + } + else + { + throw new CompilerInternalError("Undefined procedure name"); + } + } + } + //statement_node sn=convert_strong(_procedure_call.func_name); + statement_node sn = convert_strong(mc); + //проверяем на случай вызова типа real(a) ... + if (/*((sn is base_function_call) && (sn as base_function_call).IsExplicitConversion) + || (sn is SemanticTree.IReferenceNode) + || (sn is SemanticTree.IGetAddrNode) + || (sn is null_const_node) + || (sn is simple_array_indexing) + || (sn is basic_function_call) + || (sn is constant_node) + || (sn is class_field_reference)*/ + !(sn is base_function_call) && !(sn is exit_procedure) && !(sn is while_break_node) && !(sn is while_continue_node) + && !(sn is repeat_break_node) && !(sn is repeat_continue_node) && !(sn is for_break_node) && !(sn is for_continue_node) + && !(sn is foreach_break_node) && !(sn is foreach_continue_node) + ) + AddError(get_location(_procedure_call), "STATEMENT_EXPECTED"); + if (sn is base_function_call bfc && bfc.IsExplicitConversion) + AddError(get_location(_procedure_call), "STATEMENT_EXPECTED"); + + return_value(sn); + //_procedure_call.func_name.visit(this); + } + + public override void visit(SyntaxTree.variant_record_type _variant_record_type) + { + throw new NotSupportedError(get_location(_variant_record_type)); + } + + public override void visit(SyntaxTree.variant_types _variant_types) + { + throw new NotSupportedError(get_location(_variant_types)); + } + + public override void visit(SyntaxTree.variant_type _variant_type) + { + throw new NotSupportedError(get_location(_variant_type)); + } + + public override void visit(SyntaxTree.variant_list _variant_list) + { + throw new NotSupportedError(get_location(_variant_list)); + } + + public override void visit(SyntaxTree.variant _variant) + { + throw new NotSupportedError(get_location(_variant)); + } + + public override void visit(SyntaxTree.string_num_definition node) + { + location loc = get_location(node); + //if (SystemLibrary.SystemLibInitializer.ShortStringType.NotFound) + // throw new NotSupportedError(loc); + type_node tn = find_type(node.name.name, loc); + if (!(tn == SystemLibrary.SystemLibrary.string_type)) + AddError(new ExpectedType(SystemLibrary.SystemLibrary.string_type.name, loc)); + constant_node cn = convert_strong_to_constant_node(node.num_of_symbols, SystemLibrary.SystemLibrary.integer_type); + int length = (cn as int_const_node).constant_value; + if (length < 1 || length > 255) + AddError(loc, "TYPE_CAN_NOT_HAVE_THIS_SIZE_{0}", SystemLibrary.SystemLibrary.string_type.name); + return_value(context.create_short_string_type(length, loc)); + } + + public override void visit(SyntaxTree.literal_const_line _literal_const_line) + { + //DarkStar Add + string s = ""; + SyntaxTree.string_const strc; + SyntaxTree.sharp_char_const sharpcharconst; + SyntaxTree.char_const charconst; + SyntaxTree.syntax_tree_node tnf = _literal_const_line.literals[0], tnl = null; + for (int i = 0; i < _literal_const_line.literals.Count; i++) + { + if ((strc = _literal_const_line.literals[i] as SyntaxTree.string_const) != null) + s = s + strc.Value; + else + if ((sharpcharconst = _literal_const_line.literals[i] as SyntaxTree.sharp_char_const) != null) + s = s + Convert.ToChar(sharpcharconst.char_num); + else + if ((charconst = _literal_const_line.literals[i] as SyntaxTree.char_const) != null) + s = s + charconst.cconst; + if (i == _literal_const_line.literals.Count - 1) + tnl = _literal_const_line.literals[i]; + } + expression_node en = new string_const_node(s, new location(tnf.source_context.begin_position.line_num, tnf.source_context.begin_position.column_num, + tnl.source_context.end_position.line_num, tnl.source_context.end_position.column_num, current_document)); + return_value(en); + } + + public override void visit(SyntaxTree.sharp_char_const _sharp_char_const) + { + return_value(new char_const_node(Convert.ToChar(_sharp_char_const.char_num), get_location(_sharp_char_const))); + } + + public override void visit(SyntaxTree.raise_statement _raise_statement) + { + throw new NotSupportedError(get_location(_raise_statement)); + } + + public override void visit(SyntaxTree.char_const _char_const) + { + expression_node en = new char_const_node(_char_const.cconst, get_location(_char_const)); + return_value(en); + } + + private bool check_if_has_enum_consts(SyntaxTree.enum_type_definition _enum_type_definition) + { + bool has_val = false; + foreach (SyntaxTree.enumerator en in _enum_type_definition.enumerators.enumerators) + { + if (en.value != null) + { + has_val = true; + } + else + if (has_val) + AddError(get_location(en), "ALL_ENUM_CONSTANTS_NEEDED"); + } + return has_val; + } + + public override void visit(SyntaxTree.enum_type_definition _enum_type_definition) + { + //SSM 15/01/16 - реализация (integer,integer) + // Если кто-то - не named_type_reference с одним ident, то надо идти по ветке типов - это не м.б.перечисление + bool is_tuple_type = false; + foreach (SyntaxTree.enumerator en in _enum_type_definition.enumerators.enumerators) + { + if (!((en.name is named_type_reference) && (en.name as named_type_reference).names.Count()==1)) + { + is_tuple_type = true; + break; + } + } + + bool is_enum = false; + if (!is_tuple_type) // Значит, все - идентификаторы и сказать пока ничего нельзя + foreach (SyntaxTree.enumerator en in _enum_type_definition.enumerators.enumerators) + { + SyntaxTree.ident id = (en.name as named_type_reference).FirstIdent; + var si = context.CurrentScope.Find(id.name); + if ((si==null) || !(si.FirstOrDefault().sym_info is type_node)) + { + if (si != null && si.FirstOrDefault().sym_info is constant_definition_node) + { + constant_definition_node ncd = si.FirstOrDefault().sym_info as constant_definition_node; + if (_enum_type_definition.source_context != null && ncd.type.location != null && ncd.type.location.begin_line_num == _enum_type_definition.source_context.begin_position.line_num + && ncd.type.location.begin_column_num == _enum_type_definition.source_context.begin_position.column_num && ncd.type.location.doc.file_name == _enum_type_definition.source_context.FileName) + { + return_value(ncd.type); + return; + } + } + is_enum = true; + break; + } + + } + + if (!is_enum) // Значит, это определение типа + { + var lt = new List(); + for (var iii=0; iii<_enum_type_definition.enumerators.enumerators.Count(); iii++) + { + var en = _enum_type_definition.enumerators.enumerators[iii]; + var name = en.name; + if (en.value != null) + AddError(get_location(en.value), "TUPLE_TYPE_ERROR"); + lt.Add(name); + } + + if (lt.Count > 7) + AddError(get_location(_enum_type_definition), "TUPLE_TYPE_ELEMENTS_COUNT_MUST_BE_LESSEQUAL_7"); + + + var l = new List(); + l.Add(new ident("?System")); // System не должно быть найдено в пользовательском коде + l.Add(new ident("Tuple")); + + var tp = new template_param_list(lt); + // значит, это Tuple - создать его, обойти и выйти + var ttr = new SyntaxTree.template_type_reference(new named_type_reference(l), tp, _enum_type_definition.source_context); + visit(ttr); + return; + } + + //end SSM + + // Если мы здесь - значит, это перечислимый тип + + //throw new NotSupportedError(get_location(_enum_type_definition)); + //ivan added + int num = 0; + List cnsts = new List(); + check_if_has_enum_consts(_enum_type_definition); + foreach (SyntaxTree.enumerator en in _enum_type_definition.enumerators.enumerators) + { + SyntaxTree.ident id = (en.name as named_type_reference).FirstIdent; // это - точно идентификаторы + + constant_definition_node cdn = context.add_const_definition(id.name, get_location(id)); + if (en.value == null) + cdn.const_value = new enum_const_node(num++, null, get_location(id)); + else + { + constant_node cn = convert_strong_to_constant_node(en.value,SystemLibrary.SystemLibrary.integer_type); + check_for_strong_constant(cn,get_location(en.value)); + cdn.const_value = new enum_const_node((cn as int_const_node).constant_value,null,get_location(id)); + } + cnsts.Add(cdn); + } + common_type_node ctn = context.create_enum_type(null, get_location(_enum_type_definition)); //_enum_type_definition.values + num = 0; + foreach (SyntaxTree.enumerator en in _enum_type_definition.enumerators.enumerators) + { + SyntaxTree.ident id = (en.name as named_type_reference).FirstIdent; + constant_definition_node cdn = context.add_const_definition(id.name, get_location(id)); + if (en.value == null) + cdn.const_value = new enum_const_node(num++, null, get_location(id)); + else + { + constant_node cn = convert_strong_to_constant_node(en.value,SystemLibrary.SystemLibrary.integer_type); + check_for_strong_constant(cn,get_location(en.value)); + cdn.const_value = new enum_const_node((cn as int_const_node).constant_value,null,get_location(id)); + } + cdn.const_value.type = ctn; + } + foreach (constant_definition_node cdn in cnsts) + cdn.const_value.type = ctn; + internal_interface ii = SystemLibrary.SystemLibrary.integer_type.get_internal_interface(internal_interface_kind.ordinal_interface); + ordinal_type_interface oti_old = (ordinal_type_interface)ii; + enum_const_node lower_value = new enum_const_node(0, ctn, ctn.loc); + enum_const_node upper_value = new enum_const_node(ctn.const_defs.Count - 1, ctn, ctn.loc); + ordinal_type_interface oti_new = new ordinal_type_interface(oti_old.inc_method, oti_old.dec_method, + oti_old.inc_value_method, oti_old.dec_value_method, + oti_old.lower_eq_method, oti_old.greater_eq_method, oti_old.lower_method, oti_old.greater_method, lower_value, upper_value, oti_old.value_to_int, oti_old.ordinal_type_to_int); + + ctn.add_internal_interface(oti_new); + //foreach (constant_definition_node cdn in cnsts) + // cdn.const_value.type = ctn; + //context.leave_block(); + context.leave_record(); + return_value(ctn); + + } + + public override void visit(SyntaxTree.record_type _record_type) + { + } + + public override void visit(SyntaxTree.record_const node) + { + if (is_typed_const_def) + { + record_constant rc = new record_constant(node.rec_consts, get_location(node)); + rc.SetType(new RecordConstType(rc.location)); + return_value(rc); + } + else + { + record_initializer ri = new record_initializer(node.rec_consts, get_location(node)); + ri.type = new RecordConstType(ri.location); + return_value(ri); + } + } + + public override void visit(SyntaxTree.record_const_definition _record_const_definition) + { + throw new NotSupportedError(get_location(_record_const_definition)); + } + + public override void visit(SyntaxTree.set_type_definition _set_type_definition) + { + // throw new NotSupportedError(get_location(_set_type_definition)); + if (SystemLibrary.SystemLibInitializer.TypedSetType == null || SystemLibrary.SystemLibInitializer.CreateSetProcedure == null) + AddError(new NotSupportedError(get_location(_set_type_definition))); + type_node el_type = convert_strong(_set_type_definition.of_type); + if (el_type.IsPointer) + AddError(get_location(_set_type_definition.of_type), "POINTERS_IN_SETS_NOT_ALLOWED"); + //if (el_type == SystemLibrary.SystemLibrary.void_type) + // AddError(new VoidNotValid(get_location(_set_type_definition.of_type))); + check_for_type_allowed(el_type, get_location(_set_type_definition.of_type)); + check_using_static_class(el_type, get_location(_set_type_definition.of_type)); + return_value(context.create_set_type(el_type, get_location(_set_type_definition))); + } + + public override void visit(SyntaxTree.known_type_definition _known_type_definition) + { + throw new NotSupportedError(get_location(_known_type_definition)); + } + + public override void visit(SyntaxTree.default_indexer_property_node _default_indexer_property_node) + { + throw new NotSupportedError(get_location(_default_indexer_property_node)); + } + + public override void visit(SyntaxTree.class_definition _class_definition) + { + if (_class_definition.keyword == class_keyword.Record && _class_definition.Parent is var_def_statement) // безымянная запись + { + // SSM 27.02.12 - всё это перенес в синтаксический визитор UnnamedRecordsCheckVisitor + /*if (_class_definition.class_parents != null && _class_definition.class_parents.Count>0) + AddError(new SimpleSemanticError(get_location(_class_definition), "UNNAMED_RECORD_CANNOT_IMPLEMENT_INTERFACE")); + var pds = _class_definition.DescendantNodes().OfType(); + if (pds.Count() > 0) + AddError(new SimpleSemanticError(get_location(pds.First()), "UNNAMED_RECORD_CANNOT_CONTAIN_METHODS")); + + var sps = _class_definition.DescendantNodes().OfType(); + if (sps.Count() > 0) + AddError(new SimpleSemanticError(get_location(sps.First()), "UNNAMED_RECORD_CANNOT_CONTAIN_PROPERTIES")); + + var cds = _class_definition.DescendantNodes().OfType(); + if (cds.Count() > 0) + AddError(new SimpleSemanticError(get_location(cds.First()), "UNNAMED_RECORD_CANNOT_CONTAIN_CONSTRUCTORS")); + if (_class_definition.body.class_def_blocks.First().access_mod.access_level != access_modifer.public_modifer) + { + var f = _class_definition.body.class_def_blocks.First(); + var loc = get_location(f); + if (loc == null) + loc = get_location(_class_definition); + AddError(new SimpleSemanticError(loc, "UNNAMED_RECORD_CAN_CONTAIN_ONLY_ONE_PUBLIC_VISIBILITY_SECTION")); + } + + if (_class_definition.body.class_def_blocks.Count > 1) + { + var el1 = _class_definition.body.class_def_blocks.ElementAt(1); + var loc = get_location(el1.access_mod); + if (loc == null) + loc = get_location(_class_definition); + AddError(new SimpleSemanticError(loc, "UNNAMED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS")); + }*/ + + } + + if (_class_definition.attribute != class_attribute.None && _class_definition.body == null) + AddError(new SimpleSemanticError(get_location(_class_definition), "CLASS_ATTRIBUTE_NOT_ALLOWED_IN_CLASS_PREDEFINTIONS")); + if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Sealed) == SyntaxTree.class_attribute.Sealed) + { + context.converted_type.SetIsSealed(true); + if (_class_definition.keyword == SyntaxTree.class_keyword.Interface || _class_definition.keyword == SyntaxTree.class_keyword.TemplateInterface) + AddError(new SimpleSemanticError(get_location(_class_definition), "INTERFACE_CANNOT_BE_SEALED")); + } + if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Auto) == SyntaxTree.class_attribute.Auto) + { + if (_class_definition.keyword == SyntaxTree.class_keyword.Interface || _class_definition.keyword == SyntaxTree.class_keyword.TemplateInterface) + AddError(new SimpleSemanticError(get_location(_class_definition), "INTERFACE_CANNOT_BE_AUTO")); + } + if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Abstract) == SyntaxTree.class_attribute.Abstract && + (_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Sealed) == SyntaxTree.class_attribute.Sealed) + AddError(get_location(_class_definition), "ABSTRACT_CLASS_CANNOT_BE_SEALED"); + if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Abstract) == SyntaxTree.class_attribute.Abstract) + { + if (_class_definition.keyword != SyntaxTree.class_keyword.Class) + AddError(get_location(_class_definition), "ATTRIBUTE_{0}_NOT_ALLOWED", "abstract"); + context.converted_type.SetIsAbstract(true); + } + if ((_class_definition.attribute & class_attribute.Static) == class_attribute.Static) + { + if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Abstract) == SyntaxTree.class_attribute.Abstract) + AddError(get_location(_class_definition), "ATTRIBUTE_{0}_NOT_ALLOWED", "abstract"); + if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Sealed) == SyntaxTree.class_attribute.Sealed) + AddError(get_location(_class_definition), "ATTRIBUTE_{0}_NOT_ALLOWED", "sealed"); + if ((_class_definition.attribute & PascalABCCompiler.SyntaxTree.class_attribute.Auto) == SyntaxTree.class_attribute.Auto) + AddError(get_location(_class_definition), "ATTRIBUTE_{0}_NOT_ALLOWED", "auto"); + if (_class_definition.keyword != SyntaxTree.class_keyword.Class) + AddError(get_location(_class_definition), "ONLY_CLASS_CAN_BE_STATIC"); + if (context.converted_type.is_generic_type_definition) + AddError(get_location(_class_definition), "STATIC_CLASS_CANNOT_BE_GENERIC"); + context.converted_type.SetIsStatic(true); + context.converted_type.SetIsSealed(true); + context.converted_type.SetIsAbstract(true); + } + switch (_class_definition.keyword) + { + case PascalABCCompiler.SyntaxTree.class_keyword.Class: + if (context.converted_type.is_value || context.converted_type.IsInterface) + { + AddError(get_location(_class_definition), "FORWARD_DECLARATION_OF_{0}_MISMATCH_DECLARATION", context.converted_type.name); + } + if ((_class_definition.class_parents != null) && (_class_definition.class_parents.types.Count > 0)) + { + if (context.converted_type.IsStatic) + AddError(get_location(_class_definition), "STATIC_CLASS_CANNOT_HAVE_PARENT"); + context.skip_check_where_sections = true; + type_node tn = ret.visit(_class_definition.class_parents.types[0]); + context.skip_check_where_sections = false; + //if (tn == context.converted_type) + if (type_table.original_types_equals(tn, context.converted_type)) + AddError(new UndefinedNameReference(tn.name, get_location(_class_definition.class_parents.types[0]))); + if (tn.IsSealed) + AddError(get_location(_class_definition.class_parents.types[0]), "PARENT_TYPE_IS_SEALED{0}", tn.name); + if (tn == SystemLibrary.SystemLibrary.value_type) + { + AddError(get_location(_class_definition.class_parents.types[0]), "CAN_NOT_INHERIT_FROM_VALUE_TYPE"); + } + if (tn.IsPointer) + { + AddError(get_location(_class_definition.class_parents.types[0]), "CAN_NOT_INHERIT_FROM_POINTER"); + } + if (tn.IsDelegate) + { + AddError(get_location(_class_definition.class_parents.types[0]), "CAN_NOT_INHERIT_FROM_FUNCTION_TYPE"); + } + if (tn == SystemLibrary.SystemLibrary.delegate_base_type || tn == SystemLibrary.SystemLibrary.system_delegate_type) + { + AddError(get_location(_class_definition.class_parents.types[0]), "CAN_NOT_INHERIT_FROM_DELEGATE_TYPE"); + } + Hashtable used_interfs = new Hashtable(); + //Если tn - это интерфейс + if (tn.IsInterface) + { + //Первым в списке предков идёт интерфейс, поэтому базовым будет object. + context.converted_type.SetBaseType(SemanticRules.ClassBaseType); + + //Добавляем интерфейс + used_interfs.Add(tn, tn); + type_table.AddInterface(context.converted_type, tn, get_location(_class_definition.class_parents.types[0])); + if (tn.is_generic_type_instance) + ret.visit(_class_definition.class_parents.types[0]); + } + else + { + if (convertion_data_and_alghoritms.ContainsForward(tn)) // SSM 20/05/2020 #2140 + { + AddError(get_location(_class_definition.class_parents.types[0]), "FORWARD_DECLARATION_{0}_AS_BASE_TYPE", tn.name); + } + if (tn.is_generic_parameter) + { + AddError(get_location(_class_definition.class_parents.types[0]), "CAN_NOT_INHERIT_FROM_GENERIC_PARAMETER"); + } + context.converted_type.SetBaseType(tn); + if (tn.is_generic_type_instance) + ret.visit(_class_definition.class_parents.types[0]); + var type_instances = generic_convertions.get_type_instances(context.converted_type); + if (type_instances != null) + foreach (generic_type_instance_info gti in type_instances) + { + gti.pseudo_instance.SetBaseType(tn); + } + } + //Теперь добавляем интерфейсы. + //Цикл с единицы, т.к. нулевой элемент уже был рассмотрен. + VisitAndAddInterfaces(context.converted_type, _class_definition.class_parents.types, 1, used_interfs); + //for (int i = 1; i < _class_definition.class_parents.types.Count; i++) + //{ + // type_node interf = ret.visit(_class_definition.class_parents.types[i]); + // AddInterface(context.converted_type, interf, get_location(_class_definition.class_parents.types[i])); + //} + } + else + { + if (!(context.converted_type.IsPartial && context.converted_type.base_type != null && context.converted_type.base_type != SemanticRules.ClassBaseType)) + context.converted_type.SetBaseType(SemanticRules.ClassBaseType); + } + + context.converted_type.is_class = true; + if (_class_definition.body == null && + (_class_definition.class_parents == null || _class_definition.class_parents.types.Count == 0)) + { + if (context.converted_type.ForwardDeclarationOnly) + { + AddError(new NameRedefinition(context.converted_type.name, context.converted_type.Location, get_location(_class_definition))); + } + context.types_predefined.Add(context.converted_type); + context.converted_type.ForwardDeclarationOnly = true; + } + else + { + context.converted_type.ForwardDeclarationOnly = false; + if (_class_definition.body == null) + { + generate_inherit_constructors(); + if (!context.converted_type.has_default_constructor) + { + generate_default_constructor(); + } + } + List names = new List(); + List types = new List(); + if ((_class_definition.IsAutoClass())) + { + // Если снова возникнет ошибка с предками в автоклассах, то не раскомментировать эти строки, а подумать, как разрешить + //if (_class_definition.class_parents!=null) + // AddError(new AutoClassMustNotHaveParents(get_location(_class_definition))); + // добавление членов автоклассов. Не забыть сделать, что от автоклассов нельзя наследовать + // Это спорный вопрос. С другой стороны от автоклассов хочется наследовать + + var cp = _class_definition.class_parents; + if (cp != null) + foreach (var c in cp.types) + { + var ff = convert_strong(c); + if (!ff.IsInterface) + AddError(new AutoClassMustNotHaveParents(get_location(_class_definition))); + + } + + SyntaxTreeBuilder.AddMembersForAutoClass(_class_definition,ref names,ref types); + + //if (names.Select(s => s.name.ToLower()).Distinct().Count() != names.Count) + + // Отдельный цикл по синт поддереву для вылавливания events + foreach (var l in _class_definition.body.class_def_blocks) + { + foreach (var m in l.members) + { + var mm = m as var_def_statement; + if (mm != null && mm.is_event) + AddError(get_location(mm), "AUTO_CLASS_MUST_NOT_HAVE_EVENTS"); + } + } + + for (var i = 0; i < types.Count; i++) + { + type_node tn = convert_strong(types[i]); + if (tn.IsEnum && types[i] is enum_type_definition) + AddError(get_location(types[i]), "AUTO_CLASS_MUST_NOT_HAVE_UNNAMED_ENUMS"); + if (tn.IsPointer) + AddError(get_location(types[i]), "AUTO_CLASS_MUST_NOT_HAVE_POINTERS"); + } + if (_class_definition.body != null) + foreach (class_members cl_mem in _class_definition.body.class_def_blocks) + { + foreach (declaration decl in cl_mem.members) + { + if (decl is var_def_statement) + { + type_definition type = (decl as var_def_statement).vars_type; + SyntaxTree.array_type arr = type as SyntaxTree.array_type; + if (type is SyntaxTree.class_definition || (arr != null && arr.indexers != null && arr.indexers.indexers.Count > 0 && arr.indexers.indexers[0] != null)) + { + AddError(get_location(type), "STRUCT_TYPE_DEFINITION_IN_AUTO_CLASS"); + } + } + } + } + } + //if (!SemanticRules.OrderIndependedNames) + + weak_node_test_and_visit(_class_definition.body); + + + } + common_type_node converted_type = context.converted_type; + context.leave_block(); + if (converted_type.IsSealed && converted_type.IsAbstract && !converted_type.IsStatic) + AddError(get_location(_class_definition), "ABSTRACT_CLASS_CANNOT_BE_SEALED"); + return; + case PascalABCCompiler.SyntaxTree.class_keyword.Record: + common_type_node ctn; + if (_record_created) + { + _record_created = false; + ctn = context.converted_type; + } + else + { + ctn = context.create_record_type(get_location(_class_definition), record_type_name); + if (record_is_generic) + { + context.create_generic_indicator(ctn); + visit_generic_params(ctn, _class_definition.template_args.idents); + } + else + { + if (_class_definition.template_args != null && _class_definition.template_args.idents != null) + { + AddError(get_location(_class_definition.template_args), "GENERIC_TYPE_NOT_ALLOWED_HERE"); + } + } + visit_where_list(_class_definition.where_section); + } + + if (context.CurrentScope is SymbolTable.BlockScope) + { + AddError(get_location(_class_definition), "RECORD_CANNOT_BE_DECLARED_IN_BLOCK"); + ctn.internal_is_value = true; + context.leave_record(); + return_value(ctn); + return; + } + + //Добавляем интерфейсы - предки. + if (_class_definition.class_parents != null) + { + VisitAndAddInterfaces(context.converted_type, _class_definition.class_parents.types, 0, new Hashtable()); + //for (int i = 0; i < _class_definition.class_parents.types.Count; i++) + //{ + // type_node interf = ret.visit(_class_definition.class_parents.types[i]); + // AddInterface(context.converted_type, interf, get_location(_class_definition.class_parents.types[i])); + //} + } + CheckWaitedRefTypes(ctn); + record_type_name = null; + record_is_generic = false; + context.converted_type.internal_is_value = true; + + if (_class_definition.body == null && + (_class_definition.class_parents == null || _class_definition.class_parents.types.Count == 0)) + { + if (context.converted_type.ForwardDeclarationOnly) + { + AddError(new NameRedefinition(context.converted_type.name, context.converted_type.Location, get_location(_class_definition))); + } + context.types_predefined.Add(context.converted_type); + context.converted_type.ForwardDeclarationOnly = true; + } + else + { + + context.converted_type.ForwardDeclarationOnly = false; + weak_node_test_and_visit(_class_definition.body); + + + } + /*if (_class_definition.body != null) + hard_node_test_and_visit(_class_definition.body); + else + { + context.converted_type.ForwardDeclarationOnly = true; + }*/ + /*if (_class_definition.body != null) + foreach (SyntaxTree.var_def_statement var in (_class_definition.body.class_def_blocks[0].members)) + { + hard_node_test_and_visit(var); + }*/ + context.leave_record(); + return_value(ctn); + return; + //ssyy owns + case PascalABCCompiler.SyntaxTree.class_keyword.Interface: + if (context.converted_type.is_value || !context.converted_type.IsInterface) + { + AddError(get_location(_class_definition), "FORWARD_DECLARATION_OF_{0}_MISMATCH_DECLARATION", context.converted_type.name); + } + if (SemanticRules.GenerateNativeCode) + context.converted_type.SetBaseType(SemanticRules.ClassBaseType); + else + context.converted_type.SetBaseType(SystemLibrary.SystemLibrary.object_type); + context.converted_type.IsInterface = true; + context.converted_type.is_class = true; + //Добавляем интерфейсы - предки. + if (_class_definition.class_parents != null) + { + VisitAndAddInterfaces(context.converted_type, _class_definition.class_parents.types, 0, new Hashtable()); + //for (int i = 0; i < _class_definition.class_parents.types.Count; i++) + //{ + // type_node interf = ret.visit(_class_definition.class_parents.types[i]); + // AddInterface(context.converted_type, interf, get_location(_class_definition.class_parents.types[i])); + //} + } + + InitInterfaceScope(context.converted_type); + + //if (_class_definition.body == null) + //{ + //throw new NotSupportedError(get_location(_class_definition)); + // throw new InterfaceForwardDeclaration(get_location(_class_definition)); + //} + if (_class_definition.body == null && + (_class_definition.class_parents == null || _class_definition.class_parents.types.Count == 0)) + { + if (context.converted_type.ForwardDeclarationOnly) + { + AddError(new NameRedefinition(context.converted_type.name, context.converted_type.Location, get_location(_class_definition))); + } + context.types_predefined.Add(context.converted_type); + context.converted_type.ForwardDeclarationOnly = true; + } + else + { + context.converted_type.ForwardDeclarationOnly = false; + weak_node_test_and_visit(_class_definition.body); + } + //hard_node_test_and_visit(_class_definition.body); + context.leave_block(); + return; + //\ssyy owns + default: + throw new NotSupportedError(get_location(_class_definition)); + } + } + + private void VisitAndAddInterfaces(common_type_node t, List types, int start, Hashtable used_interfaces) + { + for (int i = start; i < types.Count; i++) + { + type_node interf = ret.visit(types[i]); + location loc = get_location(types[i]); + if (used_interfaces[interf] != null) + { + AddError(loc, "INTERFACE_{0}_ALREADY_ADDED_TO_IMPLEMENTING_LIST", interf.PrintableName); + } + used_interfaces.Add(interf, interf); + check_cycle_interface_inheritance(t, interf, new List()); + type_table.AddInterface(t, interf, loc); + } + } + + private void InitInterfaceScope(common_type_node ctn) + { + List interf_scopes = new List(ctn.ImplementingInterfaces.Count); + foreach (type_node tnode in ctn.ImplementingInterfaces) + { + interf_scopes.Add(tnode.Scope); + } + (ctn.Scope as SymbolTable.InterfaceScope).TopInterfaceScopeArray = + interf_scopes.ToArray(); + } + + private void visit_function_realizations(SyntaxTree.declarations _decls) + { + foreach (SyntaxTree.declaration sd in _decls.defs) + { + common_namespace_function_node cnfn = context.get_method_to_realize(sd) as common_namespace_function_node; + if (cnfn != null) + { + context.push_function(cnfn); + + if ((sd as SyntaxTree.procedure_definition).proc_body != null) + { + hard_node_test_and_visit((sd as SyntaxTree.procedure_definition).proc_body); + add_clip_for_set(context.top_function); + context.leave_block(); + } + } + } + } + + private void visit_class_member_realizations(SyntaxTree.class_body_list _class_body) + { + if (context.converted_type.internal_is_value) + { + context.add_equal_operator_if_need(); + context.add_notequal_operator_if_need(); + } + + foreach (SyntaxTree.class_members clmem in _class_body.class_def_blocks) + { + foreach (SyntaxTree.declaration sd in clmem.members) + { + common_method_node cmn = context.get_method_to_realize(sd) as common_method_node; + + if (cmn != null) + { + // frninja 20/05/16 - ставим флаг is_yield_helper + if (sd is SyntaxTree.procedure_definition) + { + cmn.is_yield_helper = (sd as SyntaxTree.procedure_definition).proc_header.is_yield_helper; + } + // end frninja + + context.push_function(cmn); + if (!cmn.IsStatic) + { + type_node self_type = cmn.cont_type; + if (cmn.cont_type.is_generic_type_definition) + self_type = cmn.cont_type.get_instance(cmn.cont_type.generic_params.ConvertAll(o => (type_node)o));// new generic_instance_type_node(self_type, self_type.generic_params.ConvertAll(o => (type_node)o), self_type.base_type, self_type.name, self_type.type_access_level, self_type.comprehensive_namespace, self_type.loc); + if (!(cmn.is_constructor && cmn.cont_type.name.StartsWith("<>local_variables_class"))) + { + local_variable lv = new local_variable(compiler_string_consts.self_word, self_type, cmn, null); + cmn.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv)); + cmn.self_variable = lv; + } + else + { + local_variable lv = new local_variable(compiler_string_consts.self_word+"$", self_type, cmn, null); + cmn.scope.AddSymbol(compiler_string_consts.self_word+"$", new SymbolInfo(lv)); + cmn.self_variable = lv; + } + } + if ((sd as SyntaxTree.procedure_definition).proc_body != null) + { + hard_node_test_and_visit((sd as SyntaxTree.procedure_definition).proc_body); + add_clip_for_set(context.top_function); + context.leave_block(); + } + } + } + } + context.clear_member_bindings(); + } + + public override void visit(SyntaxTree.class_body_list _class_body) + { + foreach (SyntaxTree.class_members clmem in _class_body.class_def_blocks) + { + //hard_node_test_and_visit(clmem); + weak_node_test_and_visit(clmem); + } + if (SemanticRules.OrderIndependedMethodNames) + { + if (!context.converted_type.is_value && !context.converted_type.IsInterface) + { + generate_inherit_constructors(); + } + if (!context.converted_type.IsInterface && !context.converted_type.has_default_constructor) + { + generate_default_constructor(); + } + if (!context.namespace_converted || context.converted_type.name.IndexOf("<>") != -1) + visit_class_member_realizations(_class_body); + } + + if (!SemanticRules.OrderIndependedMethodNames) + { + if (!context.converted_type.is_value && !context.converted_type.IsInterface) + { + generate_inherit_constructors(); + } + if (!context.converted_type.IsInterface && !context.converted_type.has_default_constructor) + { + generate_default_constructor(); + } + } + + } + + private bool disable_order_independ; + + + //ssyy + public void generate_default_constructor() + { + if (context.converted_type.IsStatic) + return; + if (!context.converted_type.is_value) + { + if (!generic_convertions.type_has_default_ctor(context.converted_type.base_type, true)) + { + //У предка нет конструктора по умолчанию, + //невозможно сгенерировать конструктор по умолчанию. + AddError(context.converted_type.loc, "NO_DEFAULT_CONSTRUCTOR_INT_TYPE_{0}", context.converted_type.base_type.name); + return; + } + } + + SyntaxTree.class_members clmem = new SyntaxTree.class_members(); + if (context.converted_type.has_user_defined_constructor) + { + clmem.access_mod = new SyntaxTree.access_modifer_node(SyntaxTree.access_modifer.protected_modifer); + } + else + { + clmem.access_mod = new SyntaxTree.access_modifer_node(SyntaxTree.access_modifer.public_modifer); + } + SyntaxTree.procedure_attributes_list pal = new PascalABCCompiler.SyntaxTree.procedure_attributes_list(); + //pal.proc_attributes.Add(new PascalABCCompiler.SyntaxTree.procedure_attribute(SyntaxTree.proc_attribute.attr_overload)); attr_overload - убрал отовсюду! ССМ + SyntaxTree.constructor constr = new PascalABCCompiler.SyntaxTree.constructor(); + constr.name = new SyntaxTree.method_name(null, null, new PascalABCCompiler.SyntaxTree.ident(compiler_string_consts.default_constructor_name), null); + constr.proc_attributes = pal; + SyntaxTree.block bl = new SyntaxTree.block(); + bl.program_code = new SyntaxTree.statement_list(); + bl.program_code.left_logical_bracket = new SyntaxTree.token_info("begin"); + bl.program_code.right_logical_bracket = new SyntaxTree.token_info("end"); + clmem.members.Add(new SyntaxTree.procedure_definition(constr, bl)); + disable_order_independ = true; + clmem.visit(this); + disable_order_independ = false; + } + //\ssyy + + public override void visit(SyntaxTree.access_modifer_node _access_modifer_node) + { + //ssyy + if (context.converted_type != null && context.converted_type.IsInterface) + { + if (_access_modifer_node.access_level == SyntaxTree.access_modifer.none) + { + context.set_field_access_level(SemanticTree.field_access_level.fal_public); + } + else + { + AddError(get_location(_access_modifer_node), "ACCESS_MODIFER_IN_INTERFACE"); + } + return; + } + //\ssyy + switch (_access_modifer_node.access_level) + { + case SyntaxTree.access_modifer.private_modifer: + { + context.set_field_access_level(SemanticTree.field_access_level.fal_private); + break; + } + case SyntaxTree.access_modifer.protected_modifer: + { + context.set_field_access_level(SemanticTree.field_access_level.fal_protected); + break; + } + case SyntaxTree.access_modifer.public_modifer: + { + context.set_field_access_level(SemanticTree.field_access_level.fal_public); + break; + } + case SyntaxTree.access_modifer.internal_modifer: + { + context.set_field_access_level(SemanticTree.field_access_level.fal_internal); + break; + } + } + } + + public override void visit(SyntaxTree.class_members _class_members) + { + foreach (var def in _class_members.members.Where(d => d is const_definition || + d is consts_definitions_list || + d is variable_definitions || + d is var_def_statement)) + { + var lambdaSearcher = new LambdaSearcher(def); + if (lambdaSearcher.CheckIfContainsLambdas()) + { + AddError(new LambdasNotAllowedInFieldsInitialization(get_location(lambdaSearcher.FoundLambda))); + } + } + + weak_node_test_and_visit(_class_members.access_mod); + foreach (SyntaxTree.declaration sd in _class_members.members) + { + hard_node_test_and_visit(sd); + } + } + + public override void visit(SyntaxTree.index_property _index_property) + { + throw new NotSupportedError(get_location(_index_property)); + } + + public override void visit(SyntaxTree.simple_property _simple_property) + { + if (_simple_property.accessors == null) + AddError(get_location(_simple_property), "PROPERTYACCESSOR_{0}_OR_{1}_EXPECTED", compiler_string_consts.PascalReadAccessorName, compiler_string_consts.PascalWriteAccessorName); + if (_simple_property.property_type == null) + AddError(get_location(_simple_property.property_name), "TYPE_NAME_EXPECTED"); + + common_property_node pn = context.add_property(_simple_property.property_name.name, + get_location(_simple_property.property_name)); + assign_doc_info(pn, _simple_property); + //pn.polymorphic_state=SemanticTree.polymorphic_state.ps_common; + //pn.loc=get_location(_simple_property.property_name); + if (context.converted_type.IsStatic && _simple_property.attr != SyntaxTree.definition_attribute.Static) + AddError(get_location(_simple_property), "STATIC_CLASSES_CANNOT_NON_STATIC_MEMBERS"); + if (_simple_property.attr == SyntaxTree.definition_attribute.Static) + { + if (context.converted_type.IsInterface) + AddError(get_location(_simple_property), "INTERFACE_PROPERTIES_CANNOT_BE_STATIC"); + pn.polymorphic_state = SemanticTree.polymorphic_state.ps_static; + } + + if (_simple_property.virt_over_none_attr == proc_attribute.attr_virtual || _simple_property.virt_over_none_attr == proc_attribute.attr_override) + pn.polymorphic_state = SemanticTree.polymorphic_state.ps_virtual; + else if (_simple_property.virt_over_none_attr == proc_attribute.attr_abstract) + { + if (context.converted_type.IsInterface) + AddError(get_location(_simple_property), "ATTRIBUTE_{0}_NOT_ALLOWED", "abstract"); + context.converted_type.SetIsAbstract(true); + pn.polymorphic_state = SemanticTree.polymorphic_state.ps_virtual_abstract; + } + if (context.converted_type.is_value_type) + { + if (_simple_property.virt_over_none_attr == proc_attribute.attr_virtual) + AddError(get_location(_simple_property), "ATTRIBUTE_{0}_NOT_ALLOWED", "virtual"); + else if (_simple_property.virt_over_none_attr == proc_attribute.attr_override) + AddError(get_location(_simple_property), "ATTRIBUTE_{0}_NOT_ALLOWED", "override"); + else if (_simple_property.virt_over_none_attr == proc_attribute.attr_reintroduce) + AddError(get_location(_simple_property), "ATTRIBUTE_{0}_NOT_ALLOWED", "reintroduce"); + else if (_simple_property.virt_over_none_attr == proc_attribute.attr_abstract) + AddError(get_location(_simple_property), "ATTRIBUTE_{0}_NOT_ALLOWED", "abstract"); + } + parameter_list pal_big = new parameter_list(); + //TODO: Спросить у Саши как получить тип параметра - var,const и т.д. + if (_simple_property.parameter_list != null) + { + foreach (SyntaxTree.property_parameter pp in _simple_property.parameter_list.parameters) + { + parameter_list pal_small = new parameter_list(); + foreach (SyntaxTree.ident id in pp.names.idents) + { + common_parameter cp = new common_parameter(id.name, SemanticTree.parameter_type.value, null, + concrete_parameter_type.cpt_none, get_location(id)); + pal_small.AddElement(cp); + } + type_node tn = convert_strong(pp.type); + foreach (parameter pr in pal_small) + { + pr.type = tn; + } + pal_big.AddRange(pal_small); + } + } + pn.parameters.AddRange(pal_big); + pn.internal_property_type = convert_strong(_simple_property.property_type); + + if (_simple_property.accessors != null) + { + + convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors); + + List sil = null; + //definition_node dn = null; + + if (_simple_property.accessors.read_accessor != null) + { + convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.read_accessor); + if (_simple_property.accessors.read_accessor.accessor_name == null) + { + if (!context.converted_type.IsInterface && _simple_property.virt_over_none_attr != proc_attribute.attr_abstract) + { + AddError(get_location(_simple_property.accessors.read_accessor), "ACCESSOR_NAME_EXPECTED"); + } + pn.internal_get_function = GenerateGetSetMethodForInterfaceProperty(pn, get_location(_simple_property.accessors.read_accessor), true); + } + else + { + if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) + AddError(get_location(_simple_property.accessors.read_accessor), "ABSTRACT_PROPERTIES_CANNOT_HAVE_IMPLEMENTATION"); + convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.read_accessor.accessor_name); + sil = context.converted_type.find_in_type(_simple_property.accessors.read_accessor.accessor_name.name, context.CurrentScope); + + location loc1 = get_location(_simple_property.accessors.read_accessor.accessor_name); + + if (sil == null) + { + //AddError(new UndefinedNameReference(_simple_property.accessors.read_accessor.accessor_name.name, loc1)); + AddError(loc1, "NAME_IN_PROPERTY_READ_SECTION_MUST_BE_FIELD_OR_METHOD_NAME"); + } + + /*if (sil.FirstOrDefault().scope != context.CurrentScope) // SSM 22/05/20 + { + AddError(loc1, "NAME_IN_PROPERTY_READ_SECTION_MUST_BE_FIELD_OR_METHOD_NAME"); + }*/ + + //dn = check_name_node_type(_simple_property.accessors.read_accessor.accessor_name.name, + // si, loc1, general_node_type.function_node, general_node_type.variable_node); + + function_node read_accessor = sil.FirstOrDefault().sym_info as function_node; + + if (read_accessor != null) + { + if (!(read_accessor as common_method_node).IsStatic && _simple_property.attr == definition_attribute.Static) + AddError(loc1,"STATIC_PROPERTY_MUST_HAVE_STATIC_ACCESSOR"); + + bool good_func = true; + bool one_func = sil.Count() == 1; + int si_index = 0; + while(si_index < sil.Count()) + { + good_func = true; + if (read_accessor.parameters.Count != pn.parameters.Count) + { + good_func = false; + if (one_func) + { + AddError(new PropertyAndReadAccessorParamsCountConvergence(read_accessor, pn, loc1)); + } + } + //TODO: Сверять типы параметров - var, const и т.д. + else + { + for (int i1 = 0; good_func && i1 < read_accessor.parameters.Count; i1++) + { + if (read_accessor.parameters[i1].parameter_type != pn.parameters[i1].parameter_type || + read_accessor.parameters[i1].type != pn.parameters[i1].type) + { + good_func = false; + if (one_func) + { + AddError(loc1, "PROPERTY_{0}_AND_READ_ACCESSOR_{1}_PARAMS_TYPE_CONVERGENCE", pn.name, read_accessor.name); + } + } + } + if (read_accessor.return_value_type == null) + { + good_func = false; + if (one_func) + { + AddError(loc1, "PROPERTY_READ_ACCESSOR_CAN_NOT_BE_PROCEDURE"); + } + } + if (read_accessor.return_value_type != pn.property_type) + { + good_func = false; + if (one_func) + { + AddError(loc1, "PROPERTY_{0}_AND_READ_ACCESSOR_{1}_RETURN_VALUE_TYPE_CONVERGENCE", pn.name, read_accessor.name); + } + } + if (read_accessor is common_method_node && (read_accessor as common_method_node).is_constructor) + { + AddError(loc1, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); + } + } + if (good_func) + { + break; + } + ++si_index; + if (si_index < sil.Count()) + { + read_accessor = sil[si_index].sym_info as function_node; + } + } + if (!good_func) + { + AddError(loc1, "NO_OVERLOAD_FUNCTION_{0}_USEFUL_FOR_ACCESSOR", read_accessor.name); + } + read_accessor = GenerateGetMethod(pn, read_accessor as common_method_node, pn.loc); + + } + else + { + class_field cfield = sil.FirstOrDefault().sym_info as class_field; + if (cfield == null) + { + AddError(loc1, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); + } + if (_simple_property.parameter_list != null) + { + AddError(loc1, "INDEX_PROPERTY_ACCESSOR_CAN_NOT_BE_VARIABLE"); + } + if (cfield.type != pn.internal_property_type) + { + AddError(loc1, "PROPERTY_TYPE_MISMATCH_ACCESSOR_FIELD_TYPE"); + } + if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", cfield.name); + if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", cfield.name); + read_accessor = GenerateGetMethodForField(pn, compiler_string_consts.GetGetAccessorName(pn.name), cfield, loc1); + } + + //Вот здесь уже можем добавить акцессор для чтения. + pn.internal_get_function = read_accessor; + } + if (pn.internal_get_function != null && pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && pn.internal_get_function.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", pn.internal_get_function.name); + if (pn.internal_get_function != null && pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && pn.internal_get_function.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + AddError(get_location(_simple_property.accessors.read_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", pn.internal_get_function.name); + } + + if (_simple_property.accessors.write_accessor != null) + { + convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.write_accessor); + if (_simple_property.accessors.write_accessor.accessor_name == null) + { + if (!context.converted_type.IsInterface && _simple_property.virt_over_none_attr != proc_attribute.attr_abstract) + { + AddError(get_location(_simple_property.accessors.write_accessor), "ACCESSOR_NAME_EXPECTED"); + } + pn.internal_set_function = GenerateGetSetMethodForInterfaceProperty(pn, get_location(_simple_property.accessors.write_accessor), false); + } + else + { + if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) + AddError(get_location(_simple_property.accessors.write_accessor), "ABSTRACT_PROPERTIES_CANNOT_HAVE_IMPLEMENTATION"); + convertion_data_and_alghoritms.check_node_parser_error(_simple_property.accessors.write_accessor.accessor_name); + sil = context.converted_type.find_in_type(_simple_property.accessors.write_accessor.accessor_name.name, context.CurrentScope); + + location loc2 = get_location(_simple_property.accessors.write_accessor.accessor_name); + + if (sil == null) + { + //AddError( new UndefinedNameReference(_simple_property.accessors.write_accessor.accessor_name.name, loc2)); + AddError(loc2, "NAME_IN_PROPERTY_WRITE_SECTION_MUST_BE_FIELD_OR_METHOD_NAME"); + } + + /*if (sil.FirstOrDefault().scope != context.CurrentScope) // SSM 22/05/20 + { + AddError(loc2, "NAME_IN_PROPERTY_WRITE_SECTION_MUST_BE_FIELD_OR_METHOD_NAME"); + }*/ + + //dn = check_name_node_type(_simple_property.accessors.write_accessor.accessor_name.name, + // si, loc2, general_node_type.function_node, general_node_type.variable_node); + + function_node write_accessor = sil.FirstOrDefault().sym_info as function_node; + + if (write_accessor != null) + { + if (!(write_accessor as common_method_node).IsStatic && _simple_property.attr == definition_attribute.Static) + AddError(loc2, "STATIC_PROPERTY_MUST_HAVE_STATIC_ACCESSOR"); + + bool good_func = true; + bool one_func = sil.Count() == 1; + int si_index = 0; + while (si_index < sil.Count()) + { + good_func = true; + if (write_accessor.parameters.Count != pn.parameters.Count + 1) + { + good_func = false; + if (one_func) + { + AddError( new PropertyAndWriteAccessorParamsCountConvergence(write_accessor, pn, loc2)); + } + } + else + { + //TODO: Сверять типы параметров - var, const и т.д. + for (int i2 = 0; good_func && i2 < pn.parameters.Count; i2++) + { + if (write_accessor.parameters[i2].parameter_type != pn.parameters[i2].parameter_type || + write_accessor.parameters[i2].type != pn.parameters[i2].type) + { + good_func = false; + if (one_func) + { + AddError(loc2, "PROPERTY_{0}_AND_WRITE_ACCESSOR_{1}_PARAMS_TYPE_CONVERGENCE", pn.name ,write_accessor.name); + } + } + } + if (write_accessor.parameters[write_accessor.parameters.Count - 1].type != pn.property_type || + write_accessor.parameters[write_accessor.parameters.Count - 1].parameter_type != PascalABCCompiler.SemanticTree.parameter_type.value) + { + good_func = false; + if (one_func) + { + AddError(loc2, "PROPERTY_{0}_AND_WRITE_ACCESSOR_LAST_PARAMETER_TYPE_CONVERGENCE", pn.name); + } + } + if (write_accessor.return_value_type != null) + { + good_func = false; + if (one_func) + { + AddError(loc2, "PROPERTY_WRITE_ACCESSOR_CAN_NOT_BE_FUNCTION"); + } + } + } + if (good_func) + { + break; + } + ++si_index; + if (si_index < sil.Count()) + { + write_accessor = sil[si_index].sym_info as function_node; + } + } + if (!good_func) + { + AddError(loc2, "NO_OVERLOAD_FUNCTION_{0}_USEFUL_FOR_ACCESSOR", write_accessor.name); + } + if (write_accessor is common_method_node && (write_accessor as common_method_node).is_constructor) + { + AddError(loc2, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); + } + write_accessor = GenerateSetMethod(pn, write_accessor as common_method_node, pn.loc); + } + else + { + class_field cfield = sil.FirstOrDefault().sym_info as class_field; + if (cfield == null) + { + AddError(loc2, "ACCESSOR_CAN_BE_FIELD_OR_METHOD_ONLY"); + } + + if (_simple_property.parameter_list != null) + { + AddError(loc2, "INDEX_PROPERTY_ACCESSOR_CAN_NOT_BE_VARIABLE"); + } + if (cfield.type != pn.internal_property_type) + { + AddError(loc2, "PROPERTY_TYPE_MISMATCH_ACCESSOR_FIELD_TYPE"); + } + if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", cfield.name); + if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfield.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", cfield.name); + write_accessor = GenerateSetMethodForField(pn, compiler_string_consts.GetSetAccessorName(pn.name), cfield, loc2); + } + //Вот здесь уже можем добавить акцессор для чтения. + pn.internal_set_function = write_accessor; + } + if (pn.internal_set_function != null && pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static && pn.internal_set_function.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_MUST_BE_STATIC", pn.internal_set_function.name); + if (pn.internal_set_function != null && pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && pn.internal_set_function.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + AddError(get_location(_simple_property.accessors.write_accessor.accessor_name), "ACCESSOR_{0}_CANNOT_BE_STATIC", pn.internal_set_function.name); + } + } + make_attributes_for_declaration(_simple_property,pn); + if (_simple_property.virt_over_none_attr == proc_attribute.attr_override) + context.set_override(pn); + //TODO: Можно сделать множество свойств по умолчанию. + if (_simple_property.array_default != null) + { + if (pn.parameters.Count == 0) + { + AddError(pn.loc, "DEFAULT_PROPERTY_MUST_BE_INDEXED"); + } + if (context.converted_type.default_property_node != null) + { + AddError(pn.loc, "DUPLICATE_DEFAULT_PROPERTY_IN_CLASS"); + } + context.converted_type.default_property = pn; + } + } + + private function_node GenerateGetMethod(common_property_node cpn, common_method_node accessor, location loc) + { + common_method_node cmn = new common_method_node( + "get_"+cpn.name, loc, cpn.common_comprehensive_type, + cpn.polymorphic_state, cpn.field_access_level, null); + cpn.common_comprehensive_type.methods.AddElement(cmn); + cmn.return_value_type = cpn.property_type; + cmn.is_overload = true; + foreach (common_parameter cp in accessor.parameters) + { + common_parameter new_cp = new common_parameter(cp.name, cp.type, cp.parameter_type, cp.common_function, cp.concrete_parameter_type, cp.default_value, loc); + cmn.parameters.AddElement(new_cp); + } + expression_node meth_call; + if (cpn.polymorphic_state == SemanticTree.polymorphic_state.ps_common || cpn.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual) + { + meth_call = new common_method_call(accessor, new this_node(cpn.common_comprehensive_type, loc), loc); + foreach (common_parameter cp in cmn.parameters) + { + (meth_call as common_method_call).parameters.AddElement(new common_parameter_reference(cp, 0, loc)); + } + } + else + { + meth_call = new common_static_method_call(accessor, loc); + foreach (common_parameter cp in cmn.parameters) + { + (meth_call as common_static_method_call).parameters.AddElement(new common_parameter_reference(cp, 0, loc)); + } + } + cmn.function_code = new return_node(meth_call, loc); + cpn.common_comprehensive_type.scope.AddSymbol("get_" + cpn.name, new SymbolInfo(cmn)); + return cmn; + } + + private function_node GenerateSetMethod(common_property_node cpn, common_method_node accessor, location loc) + { + common_method_node cmn = new common_method_node( + "set_" + cpn.name, loc, cpn.common_comprehensive_type, + cpn.polymorphic_state, cpn.field_access_level, null); + cpn.common_comprehensive_type.methods.AddElement(cmn); + //cmn.return_value_type = cpn.property_type; + cmn.is_overload = true; + foreach (common_parameter cp in accessor.parameters) + { + common_parameter new_cp = new common_parameter(cp.name, cp.type, cp.parameter_type, cp.common_function, cp.concrete_parameter_type, cp.default_value, loc); + cmn.parameters.AddElement(new_cp); + } + expression_node meth_call; + if (cpn.polymorphic_state == SemanticTree.polymorphic_state.ps_common || cpn.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual) + { + meth_call = new common_method_call(accessor, new this_node(cpn.common_comprehensive_type, loc), loc); + foreach (common_parameter cp in cmn.parameters) + { + (meth_call as common_method_call).parameters.AddElement(new common_parameter_reference(cp, 0, loc)); + } + } + else + { + meth_call = new common_static_method_call(accessor, loc); + foreach (common_parameter cp in cmn.parameters) + { + (meth_call as common_static_method_call).parameters.AddElement(new common_parameter_reference(cp, 0, loc)); + } + } + cmn.function_code = meth_call; + cpn.common_comprehensive_type.scope.AddSymbol("set_" + cpn.name, new SymbolInfo(cmn)); + return cmn; + } + + internal function_node GenerateSetMethodForField(common_property_node cpn, string AcessorName, class_field cf, location loc) + { + List exist_sil = context.find_only_in_namespace(AcessorName); + if (exist_sil != null && exist_sil.FirstOrDefault().sym_info.general_node_type != general_node_type.function_node) + { + AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", AcessorName); + } + if (exist_sil != null) + { + foreach (SymbolInfo exist_si in exist_sil) + { + function_node ff = (function_node)(exist_si.sym_info); + if (ff.parameters.Count == 1 && ff.parameters[0].type == cf.type) + { + AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", AcessorName); + } + } + } + common_method_node cmn = new common_method_node( + AcessorName, loc, /*cf.cont_type,*/ cpn.comprehensive_type as common_type_node, + cf.polymorphic_state, context.get_field_access_level(), null); + cpn.common_comprehensive_type.methods.AddElement(cmn); + common_parameter cp = new common_parameter( + compiler_string_consts.value, cf.type, SemanticTree.parameter_type.value, + cmn, concrete_parameter_type.cpt_none, null, loc); + cmn.parameters.AddElement(cp); + cmn.is_overload = true; + common_parameter_reference cpr = new common_parameter_reference(cp, 0, loc); + expression_node var_ref; + if (cf.polymorphic_state == SemanticTree.polymorphic_state.ps_common) + { + var_ref = new class_field_reference(cf, new this_node(cf.type, loc), loc); + } + else + { + var_ref = new static_class_field_reference(cf, loc); + } + cmn.function_code = find_operator(compiler_string_consts.assign_name, var_ref, cpr, loc); + cf.cont_type.Scope.AddSymbol(AcessorName, new SymbolInfo(cmn)); + return cmn; + } + + internal expression_node make_assign_operator(addressed_expression left, expression_node right, location loc) + { + return find_operator(compiler_string_consts.assign_name, left, right, loc); + } + + internal function_node GenerateGetMethodForField(common_property_node cpn, string AcessorName, class_field cf, location loc) + { + List exist_sil = context.find_only_in_namespace(AcessorName); + if (exist_sil != null && exist_sil.FirstOrDefault().sym_info.general_node_type != general_node_type.function_node) + { + AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", AcessorName); + } + if (exist_sil != null) + { + foreach (SymbolInfo exist_si in exist_sil) + { + if (((function_node)(exist_si.sym_info)).parameters.Count == 0) + { + AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", AcessorName); + } + } + } + common_method_node cmn = new common_method_node( + AcessorName, loc, /*cf.cont_type,*/ cpn.comprehensive_type as common_type_node, + cf.polymorphic_state, context.get_field_access_level(), null); + cpn.common_comprehensive_type.methods.AddElement(cmn); + cmn.return_value_type = cf.type; + cmn.is_overload = true; + expression_node var_ref; + if (cf.polymorphic_state == SemanticTree.polymorphic_state.ps_common) + { + var_ref = new class_field_reference(cf, new this_node(cf.type, loc), loc); + } + else + { + var_ref = new static_class_field_reference(cf, loc); + } + cmn.function_code = new return_node(var_ref, loc); + cf.cont_type.Scope.AddSymbol(AcessorName, new SymbolInfo(cmn)); // scope -> Scope SSM 23/05/20 - + return cmn; + } + + private function_node GenerateGetSetMethodForInterfaceProperty(common_property_node pn, location loc, bool get_meth) + { + + string AcessorName = (get_meth) ? + compiler_string_consts.GetGetAccessorName(pn.name) : + compiler_string_consts.GetSetAccessorName(pn.name); + List exist_sil = context.find_only_in_namespace(AcessorName); + if (exist_sil != null && exist_sil.FirstOrDefault().sym_info.general_node_type != general_node_type.function_node) + { + AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", AcessorName); + } + common_method_node cmn = new common_method_node( + AcessorName, loc, pn.common_comprehensive_type, + pn.polymorphic_state, context.get_field_access_level(), null); + cmn.is_overload = true; + foreach (common_parameter cp in pn.parameters) + { + common_parameter accp = new common_parameter(cp.name, cp.parameter_type, cmn, cp.concrete_parameter_type, cp.loc); + accp.type = cp.type; + accp.inital_value = cp.inital_value; + accp.intrenal_is_params = cp.intrenal_is_params; + accp.is_ret_value = cp.is_ret_value; + cmn.parameters.AddElement(accp); + } + if (get_meth) + { + cmn.return_value_type = pn.internal_property_type; + } + else + { + //foreach (common_parameter par in cmn.parameters) + //{ + // if (par.name == + //} + common_parameter accp = new common_parameter(compiler_string_consts.value_in_accessor_name, + SemanticTree.parameter_type.value, cmn, concrete_parameter_type.cpt_none, null); + accp.type = pn.internal_property_type; + cmn.parameters.AddElement(accp); + } + if (exist_sil != null) + { + foreach (SymbolInfo exist_si in exist_sil) + { + if (convertion_data_and_alghoritms.function_eq_params(cmn, (function_node)(exist_si.sym_info))) + { + AddError(loc, "CAN_NOT_GENERATE_ACCESSOR_{0}", cmn.name); + } + } + } + pn.common_comprehensive_type.methods.AddElement(cmn); + pn.common_comprehensive_type.scope.AddSymbol(AcessorName, new SymbolInfo(cmn)); + return cmn; + } + + public override void visit(SyntaxTree.property_accessors _property_accessors) + { + throw new NotSupportedError(get_location(_property_accessors)); + } + + public override void visit(SyntaxTree.read_accessor_name _read_accessor_name) + { + throw new NotSupportedError(get_location(_read_accessor_name)); + } + + public override void visit(SyntaxTree.write_accessor_name _write_accessor_name) + { + throw new NotSupportedError(get_location(_write_accessor_name)); + } + + public override void visit(SyntaxTree.array_const _array_const) + { + if (_array_const.elements != null) + { + List elements = new List(); + List exprs = new List(); + foreach (SyntaxTree.expression expr in _array_const.elements.expressions) + { + if (is_typed_const_def) + elements.Add(convert_strong_to_constant_node(expr)); + else + exprs.Add(convert_strong(expr)); + } + if (is_typed_const_def) + { + array_const arrc = new array_const(elements, get_location(_array_const)); + arrc.SetType(new ArrayConstType(elements[0].type, elements.Count, arrc.location)); + return_value(arrc); + } + else + { + array_initializer arrc = new array_initializer(exprs, get_location(_array_const)); + arrc.type = new ArrayConstType(exprs[0].type, exprs.Count, arrc.location); + return_value(arrc); + } + } + else + { + //это пустой инициализатор записи + record_constant rc = new record_constant(new List(), get_location(_array_const)); + rc.SetType(new RecordConstType(get_location(_array_const))); + return_value(rc); + } + } + + private expressions_list get_set_initializer(expression_node cnfc) + { + return set_intls[cnfc]; + } + + private void add_set_initializer(expression_node cnfc, expressions_list exprs) + { + set_intls[cnfc] = exprs; + } + + private expression_node convert_diap_for_set(SyntaxTree.diapason_expr _diapason_expr, out type_node elem_type) + { + expression_node left = convert_strong(_diapason_expr.left); + if (left is typed_expression) left = convert_typed_expression_to_function_call(left as typed_expression); + expression_node right = convert_strong(_diapason_expr.right); + if (right is typed_expression) right = convert_typed_expression_to_function_call(right as typed_expression); + internal_interface ii = left.type.get_internal_interface(internal_interface_kind.ordinal_interface); + if (ii == null) + { + AddError(new OrdinalTypeExpected(left.location)); + } + internal_interface iir = right.type.get_internal_interface(internal_interface_kind.ordinal_interface); + if (iir == null) + { + AddError(new OrdinalTypeExpected(right.location)); + } + type_node_list tnl = new type_node_list(); + tnl.AddElement(left.type); + tnl.AddElement(right.type); + elem_type = convertion_data_and_alghoritms.select_base_type(tnl,true); + if (elem_type == SystemLibrary.SystemLibrary.object_type) + AddError(new SimpleSemanticError(get_location(_diapason_expr), "BAD_DIAPASON_IN_SET_TYPE")); + expression_node l = convertion_data_and_alghoritms.explicit_convert_type(left, PascalABCCompiler.SystemLibrary.SystemLibrary.integer_type); + expression_node r = convertion_data_and_alghoritms.explicit_convert_type(right, PascalABCCompiler.SystemLibrary.SystemLibrary.integer_type); + if (PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateDiapason.sym_info is common_namespace_function_node) + { + common_namespace_function_node cnfn = PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateDiapason.sym_info as common_namespace_function_node; + if (elem_type == PascalABCCompiler.SystemLibrary.SystemLibrary.char_type || elem_type == PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type || elem_type.IsEnum) + cnfn = PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateObjDiapason.sym_info as common_namespace_function_node; + common_namespace_function_call cnfc = new common_namespace_function_call(cnfn, get_location(_diapason_expr)); + if (elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.char_type && elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type && !elem_type.IsEnum) + { + cnfc.parameters.AddElement(l); + cnfc.parameters.AddElement(r); + } + else + { + cnfc.parameters.AddElement(left); + cnfc.parameters.AddElement(right); + } + return cnfc; + } + else + { + compiled_function_node cnfn = PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateDiapason.sym_info as compiled_function_node; + if (elem_type == PascalABCCompiler.SystemLibrary.SystemLibrary.char_type || elem_type == PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type || elem_type.IsEnum) + cnfn = PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateObjDiapason.sym_info as compiled_function_node; + compiled_static_method_call cnfc = new compiled_static_method_call(cnfn, get_location(_diapason_expr)); + if (elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.char_type && elem_type != PascalABCCompiler.SystemLibrary.SystemLibrary.bool_type && !elem_type.IsEnum) + { + cnfc.parameters.AddElement(l); + cnfc.parameters.AddElement(r); + } + else + { + cnfc.parameters.AddElement(left); + cnfc.parameters.AddElement(right); + } + return cnfc; + } + + } + + public override void visit(SyntaxTree.pascal_set_constant _pascal_set_constant) + { + //throw new NotSupportedError(get_location(_pascal_set_constant)); + if (SystemLibrary.SystemLibInitializer.TypedSetType == null || SystemLibrary.SystemLibInitializer.CreateSetProcedure == null) + AddError(new NotSupportedError(get_location(_pascal_set_constant))); + expressions_list consts = new expressions_list(); + type_node el_type = null; + type_node_list types = new type_node_list(); + if (_pascal_set_constant.values != null && _pascal_set_constant.values.expressions != null) + foreach (SyntaxTree.expression e in _pascal_set_constant.values.expressions) + { + if (e is SyntaxTree.nil_const) + ErrorsList.Add(new SimpleSemanticError(get_location(e), "NIL_IN_SET_CONSTRUCTOR_NOT_ALLOWED")); + else + if (e is SyntaxTree.diapason_expr) + { + expression_node en = convert_diap_for_set((e as SyntaxTree.diapason_expr), out el_type); + consts.AddElement(en); + if (el_type.IsPointer) + ErrorsList.Add(new SimpleSemanticError(get_location(e), "POINTERS_IN_SETS_NOT_ALLOWED")); + types.AddElement(el_type); + } + else + { + expression_node en = convert_strong(e); + if (en is typed_expression) en = convert_typed_expression_to_function_call(en as typed_expression); + if (en.type.type_special_kind == SemanticTree.type_special_kind.short_string) + en.type = SystemLibrary.SystemLibrary.string_type; + consts.AddElement(en); + types.AddElement(en.type); + } + } + type_node ctn = null; + if (consts.Count > 0) + { + el_type = convertion_data_and_alghoritms.select_base_type(types, true); + if (el_type == null) + AddError(new SimpleSemanticError(get_location(_pascal_set_constant), "IMPOSSIBLE_TO_INFER_SET_TYPE")); + + ctn = context.create_set_type(el_type, get_location(_pascal_set_constant)); + + } + else ctn = SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node; + + /*if (el_type == SystemLibrary.SystemLibrary.string_type) + { + for (int i = 0; i < consts.Count; i++) + if (consts[i].type == SystemLibrary.SystemLibrary.char_type) + { + consts[i] = convertion_data_and_alghoritms.convert_type(consts[i], el_type); + } + } */ // Не работает ! SSM 19.03.19 + + expressions_list consts_copy = new expressions_list(); + consts_copy.AddRange(consts); + + function_node fn = convertion_data_and_alghoritms.select_function(consts, SystemLibrary.SystemLibInitializer.CreateSetProcedure.SymbolInfo, (SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info is common_namespace_function_node)?(SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node).loc:null); + + + if (fn is common_namespace_function_node) + { + common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, get_location(_pascal_set_constant)); + add_set_initializer(cnfc, consts_copy); + cnfc.ret_type = ctn; + for (int i = 0; i < consts.Count; i++) + cnfc.parameters.AddElement(consts[i]); + return_value(cnfc); + } + else + { + compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, get_location(_pascal_set_constant)); + add_set_initializer(cnfc, consts_copy); + cnfc.ret_type = ctn; + for (int i = 0; i < consts.Count; i++) + cnfc.parameters.AddElement(consts[i]); + return_value(cnfc); + } + //return_value(new common_namespace_function_call_as_constant(cnfc,cnfc.location)); + } + + public override void visit(SyntaxTree.array_const_new acn) + { + var lst = acn.elements.expressions.Select(ex => { var semex = convert_strong(ex); try_convert_typed_expression_to_function_call(ref semex); return semex; }).ToList(); + + type_node_list types = new type_node_list(); + foreach (var tn in lst.Select(ex => ex.type)) + types.AddElement(tn); + var el_type = convertion_data_and_alghoritms.select_base_type_for_arr_const_new(types, lst, true); + var syntax_type = new SyntaxTree.semantic_type_node(el_type); + //SyntaxTree.semantic_addr_value sav; + var plist = new SyntaxTree.expression_list(new int32_const(acn.elements.Count)); + var nn = new SyntaxTree.new_expr(syntax_type, plist, true, new SyntaxTree.array_const(acn.elements, acn.elements.source_context), acn.source_context); + visit(nn); + } + + + internal List get_function_instances(List sil, List type_pars, string name, location loc, bool stop_on_error) + { + List tparams = visit_type_list(type_pars); + for (int i = 0; i < tparams.Count; i++) + { + CompilationErrorWithLocation err = generic_parameter_eliminations.check_type_generic_useful(tparams[i], loc); + if (err != null) + { + AddError(err); + } + } + List start = null; + if (sil != null) + { + foreach (SymbolInfo si in sil) + { + function_node fn = si.sym_info as function_node; + if (fn != null) + { + function_node inst = fn.get_instance(tparams, stop_on_error, loc); + if (inst != null) + { + SymbolInfo s = new SymbolInfo(inst); + if (start == null) + { + start = new List { s }; + } + else + { + start.Add(s); + } + } + } + } + } + if (start == null) + { + AddError(loc, "NO_FUNCTIONS_{0}_CAN_BE_USED_WITH_THIS_SPECIFICATION", name); + } + return start; + } + + private List get_generic_functions(List funcs, bool stop_on_none, location loc) + { + List start = null; + if (funcs != null) { + foreach (SymbolInfo func in funcs) + { + function_node f = func.sym_info as function_node; + if (f.is_generic_function) + { + //Проверяем на совпадение + bool found = false; + if (start != null) + { + foreach (SymbolInfo fsi in start) + { + if (fsi == func) + break; + if (convertion_data_and_alghoritms.function_eq_params(fsi.sym_info as function_node, f)) + { + found = true; + break; + } + } + } + if (!found) + { + if (start == null) + { + start = new List { func }; + } + else + { + start.Add(func); + } + } + } + } + } + if (start == null) + { + if (stop_on_none) + { + AddError(loc, "TRIANGLE_BRACKETS_NOT_ALLOWED_WITH_COMMON_FUNCTIONS"); + } + return null; + } + return start; + } + + private void visit_mc_helper(motivation mot, expression_node expr_node, location loc, expressions_list exprs, string msg, bool check_loop_variable = false) + { + switch (mot) + { + case motivation.expression_evaluation: + { + // SSM 28/11/18 Проверка, что var-параметры не являются параметрами цикла for или foreach + if (check_loop_variable) + { + var fc = expr_node as base_function_call; + if (fc != null) // здесь обрезаются такие волшебные функции как exit, у которых базовый тип - expr_node. Для них var-параметры проверяются отдельно (это Inc, Dec, Read) + { + var fun = fc.function; + for (var i = 0; i < fun.parameters.Length; i++) + { + if (fun.parameters[i].parameter_type == SemanticTree.parameter_type.var) + { + check_on_loop_variable(exprs[i]); + } + } + } + } + + return_value(expr_node); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(expr_node); + return; + } + default: + { + AddError(loc, msg); + return; + } + } + } + + class SymInfoComparer: EqualityComparer + { + public override bool Equals(SymbolInfo x, SymbolInfo y) + { + return x.sym_info == y.sym_info; + } + public override int GetHashCode(SymbolInfo codeh) + { + return 0; + } + } + + internal void visit_method_call(SyntaxTree.method_call _method_call) + { + // frninja 01/03/16 - for iterator capturing (yield) + if (_method_call.dereferencing_value is yield_unknown_ident) + { + var nodeToVisit = new method_call(ProcessUnknownIdent(_method_call.dereferencing_value as yield_unknown_ident), _method_call.parameters); + visit(nodeToVisit); + return; + } + // end frninja + + //lroman + if (_method_call.dereferencing_value is closure_substituting_node) + { + var nodeToVisit = + new method_call(((closure_substituting_node)_method_call.dereferencing_value).substitution, + _method_call.parameters); + visit(nodeToVisit); + return; + } + + if (_method_call.dereferencing_value is dot_node dn && dn.right is operator_name_ident) + { + AddError(get_location(dn.right), "OPERATIONS_CANNOT_BE_CALLED_USING_THIS_SYNTAX"); + } + + bool proc_wait = procedure_wait; + bool lambdas_are_in_parameters = false; //lroman// + + var syntax_nodes_parameters = _method_call.parameters == null + ? new List() + : _method_call.parameters.expressions; + if (procedure_wait) + { + procedure_wait = false; + } + //throw new ArgumentNullException("test"); + + var mot = motivation_keeper.motivation; + motivation_keeper.reset(); + + expression_node expr_node = null; + expressions_list exprs = new expressions_list(); + + SyntaxTree.ident id = null; + + List sil = null; + + type_node to_type = null; + + SyntaxTree.addressed_value deref_value = _method_call.dereferencing_value; + int templ_args_count = 0; + //bool needs_generic_type_search = false; + SyntaxTree.ident_with_templateparams iwt = deref_value as SyntaxTree.ident_with_templateparams; + if (iwt != null) + { + deref_value = iwt.name; + templ_args_count = iwt.template_params.params_list.Count; + //needs_generic_type_search = _method_call.parameters.expressions.Count == 1; + } + + SyntaxTree.inherited_ident inh_id = deref_value as SyntaxTree.inherited_ident; + if (inh_id != null) + { + inherited_ident_processing = true; + sil = find_in_base(inh_id); + if (sil != null) + if (sil.FirstOrDefault().sym_info is common_method_node) + { + if ((sil.FirstOrDefault().sym_info as common_method_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) + AddError(get_location(inh_id), "CANNOT_CALL_ABSTRACT_METHOD"); + } + else + if (sil.FirstOrDefault().sym_info is compiled_function_node) + { + if ((sil.FirstOrDefault().sym_info as compiled_function_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) + AddError(get_location(inh_id), "CANNOT_CALL_ABSTRACT_METHOD"); + } + id = inh_id; + } + else + { + id = deref_value as SyntaxTree.ident; + if (id != null && id.name != null && id.name.IndexOf('.') != -1) + { + var arr = id.name.Split('.'); + deref_value = new dot_node(new ident(id.name.Substring(0, id.name.LastIndexOf('.')), id.source_context), new ident(arr[arr.Length-1],id.source_context)); + id = null; + } + if (id != null) + { + + if (templ_args_count != 0) + { + //Ищем generics + sil = context.find(id.name + compiler_string_consts.generic_params_infix + templ_args_count.ToString()); + if (sil != null) + { + sil = new List { new SymbolInfo(get_generic_instance(sil?.FirstOrDefault(), iwt.template_params.params_list)) }; + iwt = null; + } + } + if (sil == null) + { + SyntaxTree.operator_name_ident oni = id as SyntaxTree.operator_name_ident; + if (oni != null) + { + sil = context.find(name_reflector.get_name(oni.operator_type)); + } + else + { + sil = context.find(id.name); + if (templ_args_count != 0 && sil != null) + { + SymbolInfo conv = ConvertTypeToInstance(sil?.FirstOrDefault(), iwt.template_params.params_list, get_location(id)); + if (conv != null) + { + sil = new List { conv }; + iwt = null; + } + } + if (sil != null && id.name.ToLower() == "reset" && sil.FirstOrDefault().sym_info is common_method_node && (sil.FirstOrDefault().sym_info as common_method_node).cont_type.name.Contains("clyield#") && _method_call.ParametersCount > 0) + { + sil = context.converted_namespace.find(id.name); + } + if (sil != null && id.name.ToLower() == "create" && context.converted_type != null && sil.FirstOrDefault().sym_info is common_method_node && (sil.FirstOrDefault().sym_info as common_method_node).is_constructor) + { + List base_si_list = context.converted_type.base_type.find(id.name); + if (base_si_list != null) + sil.AddRange(base_si_list); + } + } + } + } + if (sil == null) + { + SyntaxTree.dot_node _dot_node = deref_value as SyntaxTree.dot_node; + if (_dot_node != null) + { + bool skip_first_parameter = false; //lroman// + bool has_extension_overload = false; + semantic_node sn = convert_semantic_strong(_dot_node.left); + + //SyntaxTree.ident id_right = ConvertOperatorNameToIdent(_dot_node.right as SyntaxTree.ident); + SyntaxTree.ident id_right = _dot_node.right as SyntaxTree.ident; + switch (sn.general_node_type) + { + case general_node_type.expression: + { + expression_node exp = (expression_node)sn; + if (exp is typed_expression) + try_convert_typed_expression_to_function_call(ref exp); + location subloc = get_location(id_right); + if (exp is typed_expression) + AddError(new UndefinedNameReference(id_right.name, subloc)); + SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; + if (oni_right != null) + { + sil = exp.type.find_in_type(name_reflector.get_name(oni_right.operator_type), context.CurrentScope); + } + else + { + sil = exp.type.find_in_type(id_right.name, context.CurrentScope); + sil = sil?.Distinct(new SymInfoComparer()).ToList(); // SSM 16/06/20 - удалил дубли для порядка + if (sil != null && sil.FirstOrDefault().sym_info != null && sil.FirstOrDefault().sym_info.semantic_node_type == semantic_node_type.wrap_def) + { + BasePCUReader.RestoreSymbols(sil, id_right.name); + } + } + + if (sil == null) + { + AddError(new UndefinedNameReference(id_right.name, subloc)); + } + + if (sil.FirstOrDefault().sym_info.general_node_type != general_node_type.function_node) + { + if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.type_node) + { + to_type = ((type_node)(sil.FirstOrDefault().sym_info)); + } + else + { + dot_node_as_expression_dot_ident(exp, id_right, motivation.expression_evaluation, _dot_node.left); + exp = ret.get_expression(); + internal_interface ii = exp.type.get_internal_interface(internal_interface_kind.delegate_interface); + if (ii == null) + { + AddError(subloc, "EXPECTED_DELEGATE"); + } + delegate_internal_interface dii = ii as delegate_internal_interface; + sil = new List { new SymbolInfo(dii.invoke_method) }; + } + } + + if (to_type != null) + { + if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1)) + { + AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED"); + } + } + List tmp_sil = sil; + if (sil != null) + { + foreach (SymbolInfo si in sil) + { + if (si.sym_info is common_namespace_function_node) + { + common_namespace_function_node cnfn = si.sym_info as common_namespace_function_node; + if (cnfn.ConnectedToType != null && !cnfn.IsOperator) + { + exprs.AddElementFirst(exp); + skip_first_parameter = true; + break; + } + } + if (si.sym_info is compiled_function_node) + { + compiled_function_node cfn = si.sym_info as compiled_function_node; + if (cfn.ConnectedToType != null) + { + exprs.AddElementFirst(exp); + skip_first_parameter = true; + if (cfn.is_generic_function) + { + //generic_convertions.DeduceFunction(cfn, exprs); + //si.sym_info = cfn.get_instance(new List(new type_node[] { exp.type }), true, get_location(_method_call)); + } + break; + } + + } + } + } + + if (skip_first_parameter) + { + List new_sil = new List(); + bool has_obj_methods = false; + if (sil != null) + { + foreach (SymbolInfo si in sil) + { + if (si.sym_info is common_namespace_function_node) + { + common_namespace_function_node cnfn = si.sym_info as common_namespace_function_node; + if (cnfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static || cnfn.ConnectedToType != null) + new_sil.Add(si); + if (cnfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cnfn.ConnectedToType == null) + has_obj_methods = true; + } + else if (si.sym_info is compiled_function_node) + { + compiled_function_node cfn = si.sym_info as compiled_function_node; + if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static || cfn.ConnectedToType != null) + new_sil.Add(si); + if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static && cfn.ConnectedToType == null) + has_obj_methods = true; + } + else if (si.sym_info is common_method_node) + { + common_method_node cfn = si.sym_info as common_method_node; + if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + new_sil.Add(si); + if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + has_obj_methods = true; + } + } + } + if (new_sil.Count() != 0) + sil = new_sil; + else + sil = null; + } + if (_method_call.parameters != null) + { + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) + { + #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов + //lroman// + if (en is SyntaxTree.function_lambda_definition) + { + lambdas_are_in_parameters = true; + ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; + } + //lroman// + #endregion + var cen = convert_strong(en); + exprs.AddElement(cen); + } + } + + expression_node subexpr1 = null; + + if (to_type != null) + { + subexpr1 = convertion_data_and_alghoritms.explicit_convert_type(exprs[0], to_type); + } + else + { + if (iwt != null) + { + sil = get_generic_functions(sil, true, subloc); + sil = get_function_instances(sil, iwt.template_params.params_list, id_right.name, subloc, sil.Count() <= 1); + } + #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим + //lroman// + if (lambdas_are_in_parameters) + { + LambdaHelper.processingLambdaParametersForTypeInference++; + // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями + List spf = null; + try + { + ThrowCompilationError = false; + function_node ffn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters); + if (ffn == null) + { + if (skip_first_parameter) + { + expressions_list ex_list = new expressions_list(); + ex_list.AddRange(exprs); + ex_list.remove_at(0); + // Последний параметр - странный. Глупо искать не в методах расширения если это - метод расширения и мы удаляем затем первый параметр + ffn = convertion_data_and_alghoritms.select_function(ex_list, sil, subloc, syntax_nodes_parameters/*,true*/); + if (ffn == null) + { + ThrowCompilationError = true; + Errors.Error last_err = LastError(); + if (/*last_err is NoFunctionWithSameParametresNum && */ErrorsList.Count > 0) + throw LastError(); + else + throw last_err; + } + RemoveLastError(); + skip_first_parameter = false; + exprs = ex_list; + ThrowCompilationError = true; + } + else + { + ThrowCompilationError = true; + throw LastError(); + } + + } + ThrowCompilationError = true; + int exprCounter = 0; + if (skip_first_parameter) + { + exprCounter++; + } + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + exprCounter++; + continue; + } + else + { + var enLambda = (SyntaxTree.function_lambda_definition)en; + LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this); + enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; + exprs[exprCounter] = convert_strong(en); + enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; + exprCounter++; + } + } + } + catch (SeveralFunctionsCanBeCalled sf) + { + spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна + } + + Exception lastmultex = null; + if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try + { // exprs - глобальная, поэтому надо копировать + int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка + // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. + // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! + int GoodVersionsCount = 0; + int GoodVersionsCountWithSameResType = 0; + for (int i = 0; i < spf.Count; i++) // цикл по версиям + { + function_node fnn = spf[i]; + try + { + int exprCounter = 0; + if (skip_first_parameter) + { + exprCounter++; + } + + expressions_list exprs1 = new expressions_list(); + exprs1.AddRange(exprs); // сделали копию + + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + exprCounter++; + continue; + } + else + { + var fld = en as SyntaxTree.function_lambda_definition; + + var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо + var fl = fld.lambda_visit_mode; + + // запомнили типы параметров лямбды - SSM + object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы + for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) + { + var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; + if (laminftypeK == null) + realparamstype[k] = null; + else realparamstype[k] = laminftypeK.real_type; + } + + // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим + var restype = fld.return_type as SyntaxTree.lambda_inferred_type; + object realrestype = null; + if (restype != null) + realrestype = restype.real_type; + LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this); + fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman + fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! + + //contextChanger.SaveContextAndUpToNearestDefSect(); + try + { + exprs1[exprCounter] = convert_strong(en); + + type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; + type_node resformaltype = fld.RealSemTypeOfResult as type_node; + var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность + if (bbb) + { + GoodVersionsCountWithSameResType += 1; + spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. + } + + /*compiled_type_node tt; + tt = fnn.parameters[exprCounter].type as compiled_type_node; + if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) + { + resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func - тип возвращаемого значения + var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность + if (bbb) + { + GoodVersionsCountWithSameResType += 1; + spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. + } + }*/ + } + catch + { + throw; + } + finally + { + LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); + // восстанавливаем сохраненный тип возвращаемого значения + if (restype != null) + restype.real_type = realrestype; + // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно + for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) + { + var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; + if (laminftypeK != null) + laminftypeK.real_type = realparamstype[k]; + } + + fld.lambda_name = lambdaName; //lroman Восстанавливаем имена + fld.lambda_visit_mode = fl; + } + + //contextChanger.RestoreCurrentContext(); + exprCounter++; + } + } + /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так + { + spfnum = -2; + break; + }*/ + + if (GoodVersionsCountWithSameResType == 0) + spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения + GoodVersionsCount += 1; + for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо + exprs[j] = exprs1[j]; + } + catch (Exception e) + { + // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать + //contextChanger.RestoreCurrentContext(); + lastmultex = e; + } + } // конец цикла по версиям + if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения + throw new SeveralFunctionsCanBeCalled(subloc, spf); + if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд + { + throw lastmultex; + //throw new NoFunctionWithSameArguments(subloc2, false); + } + + int kk = 0; + if (skip_first_parameter) + kk++; + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + kk++; + continue; + } + else + { + LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); + exprs[kk] = convert_strong(en); + kk++; + } + } + } + // SSM 21.05.14 end + LambdaHelper.processingLambdaParametersForTypeInference--; + } + //lroman// + #endregion + + function_node fn = null; + if (!skip_first_parameter || sil.Count() == 1) + fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters); + else + { + try + { + ThrowCompilationError = false; + fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters); + if (fn == null && skip_first_parameter) + { + if (sil.Count() == 1) + { + ThrowCompilationError = true; + throw LastError(); + } + Errors.Error last_err = LastError(); + skip_first_parameter = false; + sil = tmp_sil; + exprs.remove_at(0); + fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters,true); + if (fn == null) + { + ThrowCompilationError = true; + RemoveLastError(); + if (last_err is CanNotConvertTypes) + { + var from_type = (last_err as CanNotConvertTypes).from; + foreach (SymbolInfo si in sil) + { + function_node si_fn = si.sym_info as function_node; + if (si_fn != null && si_fn.is_extension_method && si_fn.parameters[0].type == from_type) + { + throw new NoFunctionWithSameParametresNum(subloc, true, si_fn); + } + } + } + throw last_err; + } + } + else if (fn != null && skip_first_parameter && sil.Count() > 1 && !sil.HasOnlyExtensionMethods()) + { + function_node tmp_fn = fn; + exprs.remove_at(0); + sil = tmp_sil; + fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters,true); + if (fn == null) + { + fn = tmp_fn; + RemoveLastError(); + exprs.AddElementFirst(exp); + } + } + } + catch (Exception ex) + { + ThrowCompilationError = true; + if (skip_first_parameter) + { + sil = tmp_sil; + exprs.remove_at(0); + fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters,true); + } + else + throw ex; + } + ThrowCompilationError = true; + } + SemanticTree.IGenericInstance igi = fn as SemanticTree.IGenericInstance; + if (igi != null) + { + //проверяем на соответствие ограничителям + int num_err; + //CompilationErrorWithLocation err = generic_parameter_eliminations.check_type_list( + } + base_function_call bfc = create_not_static_method_call(fn, exp, get_location(id_right), proc_wait); + bfc.parameters.AddRange(exprs); + subexpr1 = bfc; + } + + visit_mc_helper(mot, subexpr1, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED",true); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(subexpr1); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(subexpr1); + return; + } + default: + { + AddError(subexpr1.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + }*/ + + } + case general_node_type.namespace_node: + { + namespace_node nsn = (namespace_node)sn; + if (templ_args_count != 0) + { + //Ищем generics + sil = context.find(id_right.name + compiler_string_consts.generic_params_infix + templ_args_count.ToString()); + if (sil != null) + { + sil = new List { new SymbolInfo(get_generic_instance(sil?.FirstOrDefault(), iwt.template_params.params_list)) }; + iwt = null; + } + } + if (sil == null) + { + SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; + if (oni_right != null) + { + sil = nsn.find(name_reflector.get_name(oni_right.operator_type)); + } + else + { + sil = nsn.findOnlyInNamespace(id_right.name); + if (templ_args_count != 0) + { + sil = nsn.find(id_right.name + compiler_string_consts.generic_params_infix + templ_args_count.ToString()); + if (sil != null) + { + sil = new List { new SymbolInfo(get_generic_instance(sil?.FirstOrDefault(), iwt.template_params.params_list)) }; + iwt = null; + } + /*SymbolInfo conv = ConvertTypeToInstance(sil?.FirstOrDefault(), iwt.template_params.params_list, get_location(id_right)); + if (conv != null) + { + sil = new List { conv }; + iwt = null; + }*/ + } + } + } + id = id_right; + break; + } + case general_node_type.unit_node: + { + unit_node un = (unit_node)sn; + SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; + if (oni_right != null) + { + sil = un.find_only_in_namespace(name_reflector.get_name(oni_right.operator_type)); + } + else + { + sil = un.find_only_in_namespace(id_right.name); + } + id = id_right; + break; + } + case general_node_type.type_node: + { + type_node tn = (type_node)sn; + + check_for_type_allowed(tn, get_location(id_right)); + SyntaxTree.operator_name_ident oni_right = id_right as SyntaxTree.operator_name_ident; + if (oni_right != null) + { + sil = tn.find_in_type(name_reflector.get_name(oni_right.operator_type), context.CurrentScope); + } + else + { + sil = tn.find_in_type(id_right.name, context.CurrentScope);//CurrentScope + delete_inherited_constructors(ref sil, tn); + delete_extension_methods(ref sil, tn); // SSM 2.2.2016 Пока временно закомментировал - в старом коде этого не было. Из-за этого не работает System.Linq.Enumerable.Select + } + + //definition_node ddn2=check_name_node_type(id_right.name,si,get_location(id_right), + // general_node_type.function_node); + + expression_node exp = null; + location subloc = get_location(id_right); + + if (sil == null) + { + AddError(new UndefinedNameReference(id_right.name, subloc)); + } + + if (sil.FirstOrDefault().sym_info.general_node_type != general_node_type.function_node) + { + if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.type_node) + { + to_type = ((type_node)(sil.FirstOrDefault().sym_info)); + } + else + { + dot_node_as_type_ident(tn, id_right, motivation.expression_evaluation); + exp = ret.get_expression(); + internal_interface ii = exp.type.get_internal_interface(internal_interface_kind.delegate_interface); + if (ii == null) + { + AddError(subloc, "EXPECTED_DELEGATE"); + } + delegate_internal_interface dii = ii as delegate_internal_interface; + sil = new List { new SymbolInfo(dii.invoke_method) }; + } + } + + if (to_type != null) + { + if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1)) + { + AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED"); + } + } + + if (_method_call.parameters != null) + { + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) + { + #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов + //lroman// + if (en is SyntaxTree.function_lambda_definition) + { + lambdas_are_in_parameters = true; + ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; + } + //lroman// + #endregion + exprs.AddElement(convert_strong(en)); + } + } + + expression_node subexpr2 = null; + + if (to_type != null) + { + + subexpr2 = convertion_data_and_alghoritms.explicit_convert_type(exprs[0], to_type); + } + else + { + if (iwt != null) + { + sil = get_generic_functions(sil, true, subloc); + sil = get_function_instances(sil, iwt.template_params.params_list, id_right.name, subloc, sil.Count() <= 1); + } + #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим + //lroman// + if (lambdas_are_in_parameters) + { + LambdaHelper.processingLambdaParametersForTypeInference++; + // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями + List spf = null; + try + { + function_node ffn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters); + int exprCounter = 0; + if (skip_first_parameter) + { + exprCounter++; + } + List params_exprs = new List(); + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + exprCounter++; + continue; + } + else + { + var enLambda = (SyntaxTree.function_lambda_definition)en; + if (ffn.parameters[Math.Min(exprCounter, ffn.parameters.Count - 1)].is_params) + { + LambdaHelper.InferTypesFromVarStmt(ffn.parameters[Math.Min(exprCounter, ffn.parameters.Count - 1)].type.element_type, enLambda, this); + enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; + if (exprCounter <= ffn.parameters.Count - 1) + exprs[exprCounter] = convert_strong(en); + else + exprs.AddElement(convert_strong(en)); + enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; + } + else + { + LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this); + enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; + exprs[exprCounter] = convert_strong(en); + enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; + + } + exprCounter++; + } + } + /*if (params_exprs.Count > 0) + { + location loc = get_location(_method_call); + typeof_operator to = new typeof_operator(params_exprs[0].type, loc); + expression_node retv = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl, loc, to, new int_const_node(params_exprs.Count, loc)); + base_function_call cnfc = retv as base_function_call; + foreach (expression_node e in params_exprs) + cnfc.parameters.AddElement(e); + exprs[exprCounter] = cnfc; + }*/ + } + catch (SeveralFunctionsCanBeCalled sf) + { + spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна + } + + Exception lastmultex = null; + if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try + { // exprs - глобальная, поэтому надо копировать + int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка + // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. + // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! + int GoodVersionsCount = 0; + int GoodVersionsCountWithSameResType = 0; + for (int i = 0; i < spf.Count; i++) // цикл по версиям + { + function_node fnn = spf[i]; + try + { + int exprCounter = 0; + if (skip_first_parameter) + { + exprCounter++; + } + + expressions_list exprs1 = new expressions_list(); + exprs1.AddRange(exprs); // сделали копию + + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + exprCounter++; + continue; + } + else + { + var fld = en as SyntaxTree.function_lambda_definition; + + var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо + var fl = fld.lambda_visit_mode; + + // запомнили типы параметров лямбды - SSM + var fld_formal_parameters_Count = fld.formal_parameters == null ? 0 : fld.formal_parameters.params_list.Count; + + object[] realparamstype = new object[fld_formal_parameters_Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы + for (var k = 0; k < fld_formal_parameters_Count; k++) + { + var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; + if (laminftypeK == null) + realparamstype[k] = null; + else realparamstype[k] = laminftypeK.real_type; + } + + // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим + var restype = fld.return_type as SyntaxTree.lambda_inferred_type; + object realrestype = null; + if (restype != null) + realrestype = restype.real_type; + LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this); + fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman + fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! + + //contextChanger.SaveContextAndUpToNearestDefSect(); + try + { + exprs1[exprCounter] = convert_strong(en); + + type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; + type_node resformaltype = fld.RealSemTypeOfResult as type_node; + var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность + if (bbb) + { + GoodVersionsCountWithSameResType += 1; + spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. + } + + /*compiled_type_node tt; + tt = fnn.parameters[exprCounter].type as compiled_type_node; + if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) + { + resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func - тип возвращаемого значения + var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность + if (bbb) + { + GoodVersionsCountWithSameResType += 1; + spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. + } + }*/ + } + catch + { + throw; + } + finally + { + LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); + // восстанавливаем сохраненный тип возвращаемого значения + if (restype != null) + restype.real_type = realrestype; + // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно + for (var k = 0; k < fld_formal_parameters_Count; k++) + { + var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; + if (laminftypeK != null) + laminftypeK.real_type = realparamstype[k]; + } + + fld.lambda_name = lambdaName; //lroman Восстанавливаем имена + fld.lambda_visit_mode = fl; + } + + //contextChanger.RestoreCurrentContext(); + exprCounter++; + } + } + /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так + { + spfnum = -2; + break; + }*/ + + if (GoodVersionsCountWithSameResType == 0) + spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения + GoodVersionsCount += 1; + for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо + exprs[j] = exprs1[j]; + } + catch (Exception e) + { + // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать + //contextChanger.RestoreCurrentContext(); + lastmultex = e; + } + } // конец цикла по версиям + if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения + throw new SeveralFunctionsCanBeCalled(subloc, spf); + if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд + { + throw lastmultex; + //throw new NoFunctionWithSameArguments(subloc2, false); + } + + int kk = 0; + if (skip_first_parameter) + kk++; + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + kk++; + continue; + } + else + { + LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); + exprs[kk] = convert_strong(en); + kk++; + } + } + } + // SSM 21.05.14 end + LambdaHelper.processingLambdaParametersForTypeInference--; + } + //lroman// + #endregion + + function_node fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters); + + base_function_call bfc2 = null; + if (exp == null) + { + bfc2 = create_static_method_call(fn, subloc, tn, proc_wait); + } + else + { + bfc2 = create_not_static_method_call(fn, exp, subloc, proc_wait); + } + bfc2.parameters.AddRange(exprs); + subexpr2 = bfc2; + } + + visit_mc_helper(mot, subexpr2, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED",true); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(subexpr2); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(subexpr2); + return; + } + default: + { + AddError(subexpr2.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + } */ + } + } + } + else + { + SyntaxTree.expression expr = deref_value as SyntaxTree.expression; + if (expr != null) + { + expression_node exp_int = convert_strong(expr); + location sloc = get_location(expr); + internal_interface ii = exp_int.type.get_internal_interface(internal_interface_kind.delegate_interface); + if (ii == null) + { + AddError(sloc, "EXPECTED_DELEGATE"); + } + delegate_internal_interface dii = (delegate_internal_interface)ii; + sil = new List { new SymbolInfo(dii.invoke_method) }; + + if (_method_call.parameters != null) + { + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) + { + #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов + //lroman// + if (en is SyntaxTree.function_lambda_definition) + { + lambdas_are_in_parameters = true; + ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; + } + //lroman// + #endregion + exprs.AddElement(convert_strong(en)); + } + } + location subloc = sloc; + #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим + //lroman// + if (lambdas_are_in_parameters) + { + LambdaHelper.processingLambdaParametersForTypeInference++; + // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями + List spf = null; + try + { + function_node ffn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc, syntax_nodes_parameters); + int exprCounter = 0; + + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + exprCounter++; + continue; + } + else + { + var enLambda = (SyntaxTree.function_lambda_definition)en; + LambdaHelper.InferTypesFromVarStmt(ffn.parameters[exprCounter].type, enLambda, this); + enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; + exprs[exprCounter] = convert_strong(en); + enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; + exprCounter++; + } + } + } + catch (SeveralFunctionsCanBeCalled sf) + { + spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна + } + + Exception lastmultex = null; + if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try + { // exprs - глобальная, поэтому надо копировать + int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка + // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. + // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! + int GoodVersionsCount = 0; + int GoodVersionsCountWithSameResType = 0; + for (int i = 0; i < spf.Count; i++) // цикл по версиям + { + function_node fnn = spf[i]; + try + { + int exprCounter = 0; + + + expressions_list exprs1 = new expressions_list(); + exprs1.AddRange(exprs); // сделали копию + + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + exprCounter++; + continue; + } + else + { + var fld = en as SyntaxTree.function_lambda_definition; + + var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо + var fl = fld.lambda_visit_mode; + + // запомнили типы параметров лямбды - SSM + object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы + for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) + { + var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; + if (laminftypeK == null) + realparamstype[k] = null; + else realparamstype[k] = laminftypeK.real_type; + } + + // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим + var restype = fld.return_type as SyntaxTree.lambda_inferred_type; + object realrestype = null; + if (restype != null) + realrestype = restype.real_type; + LambdaHelper.InferTypesFromVarStmt(fnn.parameters[exprCounter].type, fld, this); + fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman + fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! + + //contextChanger.SaveContextAndUpToNearestDefSect(); + try + { + exprs1[exprCounter] = convert_strong(en); + + type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; + type_node resformaltype = fld.RealSemTypeOfResult as type_node; + var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность + if (bbb) + { + GoodVersionsCountWithSameResType += 1; + spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. + } + + /*compiled_type_node tt; + tt = fnn.parameters[exprCounter].type as compiled_type_node; + if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) + { + resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func - тип возвращаемого значения + var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность + if (bbb) + { + GoodVersionsCountWithSameResType += 1; + spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. + } + }*/ + } + catch + { + throw; + } + finally + { + LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); + // восстанавливаем сохраненный тип возвращаемого значения + if (restype != null) + restype.real_type = realrestype; + // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно + for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) + { + var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; + if (laminftypeK != null) + laminftypeK.real_type = realparamstype[k]; + } + + fld.lambda_name = lambdaName; //lroman Восстанавливаем имена + fld.lambda_visit_mode = fl; + } + + //contextChanger.RestoreCurrentContext(); + exprCounter++; + } + } + /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так + { + spfnum = -2; + break; + }*/ + + if (GoodVersionsCountWithSameResType == 0) + spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения + GoodVersionsCount += 1; + for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо + exprs[j] = exprs1[j]; + } + catch (Exception e) + { + // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать + //contextChanger.RestoreCurrentContext(); + lastmultex = e; + } + } // конец цикла по версиям + if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения + throw new SeveralFunctionsCanBeCalled(subloc, spf); + if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд + { + throw lastmultex; + //throw new NoFunctionWithSameArguments(subloc2, false); + } + + int kk = 0; + + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + kk++; + continue; + } + else + { + LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); + exprs[kk] = convert_strong(en); + kk++; + } + } + } + // SSM 21.05.14 end + LambdaHelper.processingLambdaParametersForTypeInference--; + } + //lroman// + #endregion + + function_node del_func = convertion_data_and_alghoritms.select_function(exprs, sil, sloc, syntax_nodes_parameters); + base_function_call bbfc = create_not_static_method_call(del_func, exp_int, sloc, proc_wait); + bbfc.parameters.AddRange(exprs); + + visit_mc_helper(mot, bbfc, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED",true); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(bbfc); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(bbfc); + return; + } + default: + { + AddError(bbfc.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + } */ + } + else + { + throw new CompilerInternalError("Unexpected method name kind"); + } + } + } + } + + //definition_node dn=check_name_node_type(id.name,si,get_location(_method_call),general_node_type.function_node); + + expression_node exp2 = null; + location subloc2 = get_location(id); + + List sibak = new List(); + if (sil != null) + sibak.AddRange(sil.GetRange(1, sil.Count() - 1)); + + if (sil == null) + { + AddError(new UndefinedNameReference(id.name, subloc2)); + } + + is_format_allowed = false; + if (SystemUnitAssigned) + { + if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(sil) || SystemLibrary.SystemLibInitializer.readln_procedure.Equal(sil)) + { + + expression_node bfcint = make_read_call(sil, _method_call.parameters, subloc2); + if (!proc_wait) + AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (sil.FirstOrDefault().sym_info as function_node).name); + + visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(bfcint); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(bfcint); + return; + } + default: + { + AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + }*/ + + return; + } + else if (SystemLibrary.SystemLibInitializer.write_procedure.Equal(sil) || SystemLibrary.SystemLibInitializer.writeln_procedure.Equal(sil) || SystemLibrary.SystemLibInitializer.StrProcedure.Equal(sil)) + { + is_format_allowed = true; + } + else if (SystemLibrary.SystemLibInitializer.PascalABCVersion.Equal(sil)) + { + return_value(new string_const_node(RevisionClass.FullVersion, get_location(_method_call))); + return; + } + else if (SystemLibrary.SystemLibInitializer.ArrayCopyFunction.Equal(sil)) + { + if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1) + { + expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); + if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_kind) + { + location loc = get_location(_method_call); + expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ArrayCopyFunction.sym_info as function_node, loc, param0); + function_node fn = convertion_data_and_alghoritms.get_empty_conversion(en.type, param0.type, false); + en = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, en); + return_value(en); + return; + } + } + } + else if (SystemLibrary.SystemLibInitializer.SetLengthProcedure.Equal(sil) || SystemLibrary.SystemLibrary.resize_func == sil.FirstOrDefault().sym_info as function_node) + { + if (_method_call.parameters != null && _method_call.parameters.expressions.Count >= 2) + { + expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); + if (!param0.is_addressed) + AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); + if (param0.type.type_special_kind == SemanticTree.type_special_kind.short_string) + { + expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); + param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.integer_type); + base_function_call cnfn = null; + if (SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info is common_namespace_function_node) + cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); + else + cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.SetLengthForShortStringProcedure.sym_info as compiled_function_node, get_location(_method_call)); + cnfn.parameters.AddElement(param0); + cnfn.parameters.AddElement(param1); + cnfn.parameters.AddElement(new int_const_node((param0.type as short_string_type_node).Length, null)); + + visit_mc_helper(mot, cnfn, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(cnfn); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(cnfn); + return; + } + default: + { + AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + } */ + } + else if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_kind) + { + int rank = 1; + if (param0.type is compiled_type_node) + rank = (param0.type as compiled_type_node).rank; + else if (param0.type is common_type_node) + rank = (param0.type as common_type_node).rank; + if (_method_call.parameters.expressions.Count - 1 != rank) + AddError(get_location(_method_call), "{0}_PARAMETERS_EXPECTED", rank + 1); + if (rank > 1) + { + type_node tn = param0.type.element_type; + location loc = get_location(_method_call); + typeof_operator to = new typeof_operator(tn, loc); + List lst = new List(); + //размер + for (int i = 1; i < _method_call.parameters.expressions.Count; i++) + { + expression_node expr = convert_strong(_method_call.parameters.expressions[i]); ; + expr = convertion_data_and_alghoritms.convert_type(expr, SystemLibrary.SystemLibrary.integer_type); + if (expr is int_const_node && (expr as int_const_node).constant_value < 0) + AddError(expr.location, "NEGATIVE_ARRAY_LENGTH_({0})_NOT_ALLOWED", (expr as int_const_node).constant_value); + lst.Add(expr); + } + //это вызов спецфункции + + expression_node retv = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.NewArrayProcedureDecl, loc, to, new int_const_node(lst.Count, loc)); + common_namespace_function_call cnfc = retv as common_namespace_function_call; + foreach (expression_node e in lst) + cnfc.parameters.AddElement(e); + expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.CopyWithSizeFunction.sym_info as function_node, loc, param0, cnfc); + function_node fn = convertion_data_and_alghoritms.get_empty_conversion(en.type, retv.type, false); + en = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, en); + basic_function_call bfc = new basic_function_call(tn.find(compiler_string_consts.assign_name).FirstOrDefault().sym_info as basic_function_node, loc, param0, en); + return_value(bfc); + return; + } + } + } + } + else if (SystemLibrary.SystemLibInitializer.InsertProcedure.Equal(sil)) + { + if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 3) + { + //expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); + expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); + //expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); + if (param1.type.type_special_kind == SemanticTree.type_special_kind.short_string) + { + expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); + expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); + param0 = convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.string_type); + param2 = convertion_data_and_alghoritms.convert_type(param2, SystemLibrary.SystemLibrary.integer_type); + base_function_call cnfn = null; + if (SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info is common_namespace_function_node) + cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); + else + cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.InsertInShortStringProcedure.sym_info as compiled_function_node, get_location(_method_call)); + cnfn.parameters.AddElement(param0); + cnfn.parameters.AddElement(param1); + cnfn.parameters.AddElement(param2); + cnfn.parameters.AddElement(new int_const_node((param1.type as short_string_type_node).Length, null)); + + visit_mc_helper(mot, cnfn, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(cnfn); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(cnfn); + return; + } + default: + { + AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + }*/ + } + } + } + else if (SystemLibrary.SystemLibInitializer.DeleteProcedure.Equal(sil)) + { + if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 3) + { + //expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); + expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); + //expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); + if (param0.type.type_special_kind == SemanticTree.type_special_kind.short_string) + { + expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); + expression_node param2 = convert_strong(_method_call.parameters.expressions[2]); + param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.integer_type); + param2 = convertion_data_and_alghoritms.convert_type(param2, SystemLibrary.SystemLibrary.integer_type); + base_function_call cnfn = null; + if (SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info is common_namespace_function_node) + cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); + else + cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.DeleteProcedure.sym_info as compiled_function_node, get_location(_method_call)); + cnfn.parameters.AddElement(param0); + cnfn.parameters.AddElement(param1); + cnfn.parameters.AddElement(param2); + + visit_mc_helper(mot, cnfn, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(cnfn); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(cnfn); + return; + } + default: + { + AddError(cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + } */ + } + } + } + else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil) + || SystemLibrary.SystemLibInitializer.ExcludeProcedure.Equal(sil)) + { + if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 2) + { + expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); + expression_node param1 = convert_strong(_method_call.parameters.expressions[1]); + param1 = convert_if_typed_expression_to_function_call(param1); + expressions_list args = new expressions_list(); + args.AddElement(param0); + args.AddElement(param1); + CheckSpecialFunctionCall(sil, args, get_location(_method_call)); + expression_node en_cnfn = null; + if (SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info is common_namespace_function_node) + { + common_namespace_function_call cnfn = null; + if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil)) cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); + else cnfn = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ExcludeProcedure.sym_info as common_namespace_function_node, get_location(_method_call)); + cnfn.parameters.AddElement(param0); + cnfn.parameters.AddElement(param1); + en_cnfn = cnfn; + } + else + { + compiled_static_method_call cnfn = null; + if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil)) cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.IncludeProcedure.sym_info as compiled_function_node, get_location(_method_call)); + else cnfn = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ExcludeProcedure.sym_info as compiled_function_node, get_location(_method_call)); + cnfn.parameters.AddElement(param0); + cnfn.parameters.AddElement(param1); + en_cnfn = cnfn; + } + + visit_mc_helper(mot, en_cnfn, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(en_cnfn); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(en_cnfn); + return; + } + default: + { + AddError(en_cnfn.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + } */ + } + } + else if (SystemLibrary.SystemLibInitializer.IncProcedure.Equal(sil)) + { + expression_node bfcint = make_inc_call(sil?.FirstOrDefault(), _method_call.parameters, subloc2); + if (!proc_wait) + AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (sil.FirstOrDefault().sym_info as function_node).name); + + visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(bfcint); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(bfcint); + return; + } + default: + { + AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + } */ + + return; + } + else if (SystemLibrary.SystemLibInitializer.DecProcedure.Equal(sil)) + { + expression_node bfcint = make_dec_call(sil?.FirstOrDefault(), _method_call.parameters, subloc2); + if (!proc_wait) + AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (sil.FirstOrDefault().sym_info as function_node).name); + + visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(bfcint); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(bfcint); + return; + } + default: + { + AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + }*/ + + return; + } + else if (SystemLibrary.SystemLibInitializer.SuccFunction.Equal(sil)) + { + expression_node bfcint = make_succ_call(sil, _method_call.parameters, subloc2); + + visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(bfcint); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(bfcint); + return; + } + default: + { + AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + }*/ + + return; + } + else if (SystemLibrary.SystemLibInitializer.PredFunction.Equal(sil)) + { + expression_node bfcint = make_pred_call(sil, _method_call.parameters, subloc2); + visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(bfcint); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(bfcint); + return; + } + default: + { + AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + } */ + + return; + } + else if (SystemLibrary.SystemLibInitializer.OrdFunction.Equal(sil)) + { + expression_node bfcint = make_ord_call(sil, _method_call.parameters, subloc2); + visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(bfcint); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(bfcint); + return; + } + default: + { + AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + } */ + + return; + } + else if (SystemLibrary.SystemLibInitializer.LowFunction.Equal(sil)) + { + if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1) + { + expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); + if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper) + { + bounded_array_interface bai = param0.type.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface; + expression_node en = new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), get_location(_method_call)); + + visit_mc_helper(mot, en, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(en); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(en); + return; + } + default: + { + AddError(en.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + }*/ + } + } + } + else if (SystemLibrary.SystemLibInitializer.HighFunction.Equal(sil)) + { + if (_method_call.parameters != null && _method_call.parameters.expressions.Count == 1) + { + expression_node param0 = convert_strong(_method_call.parameters.expressions[0]); + if (param0.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper) + { + bounded_array_interface bai = param0.type.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface; + expression_node en = new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.upper_value), get_location(_method_call)); + + visit_mc_helper(mot, en, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(en); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(en); + return; + } + default: + { + AddError(en.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + } */ + } + } + } + else if (sil.FirstOrDefault() == SystemLibrary.SystemLibInitializer.NewProcedure) + { + expression_node bfcint = make_new_call(sil.FirstOrDefault(), _method_call.parameters, subloc2); + if (!proc_wait) + AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (sil.FirstOrDefault().sym_info as function_node).name); + + visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(bfcint); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(bfcint); + return; + } + default: + { + AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + }*/ + + return; + } + else if (sil.FirstOrDefault() == SystemLibrary.SystemLibInitializer.DisposeProcedure) + { + //if (convertion_data_and_alghoritms.select_function(convert_expression_list(_method_call.parameters.expressions), si, subloc2) == SystemLibrary.SystemLibInitializer.DisposeProcedure.sym_info) + //{ + expression_node bfcint = make_dispose_call(sil.FirstOrDefault(), _method_call.parameters, subloc2); + if (!proc_wait) + AddError(subloc2, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", (sil.FirstOrDefault().sym_info as function_node).name); + + visit_mc_helper(mot, bfcint, get_location(_method_call), exprs, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(bfcint); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(bfcint); + return; + } + default: + { + AddError(bfcint.location, "EXPRESSION_IS_NOT_ADDRESSED"); + return; + } + }*/ + + return; + // } + } + else if (SystemLibrary.SystemLibInitializer.AssertProcedure.Equal(sil)) + { + // return_value(new empty_statement(null)); + // return; + } + /*else if (SystemLibrary.SystemLibInitializer.IncProcedure != null && SystemLibrary.SystemLibInitializer.IncProcedure.Equal(si)) + { + expression_node bfcint = make_inc_call(si, _method_call.parameters, subloc2); + }*/ + } + if (sil.FirstOrDefault().sym_info.general_node_type != general_node_type.function_node) + { + if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.type_node) + { + to_type = ((type_node)(sil.FirstOrDefault().sym_info)); + /*if (to_type == SystemLibrary.SystemLibrary.void_type) + { + throw new VoidNotValid(subloc2); + }*/ + check_for_type_allowed(to_type, subloc2); + } + else + { + exp2 = ident_value_reciving(sil, id); + internal_interface ii = exp2.type.get_internal_interface(internal_interface_kind.delegate_interface); + if (ii == null) + { + AddError(subloc2, "EXPECTED_DELEGATE"); + } + if (exp2 is nonstatic_event_reference) + { + nonstatic_event_reference nser = exp2 as nonstatic_event_reference; + common_event ce = nser.en as common_event; + if (ce != null) + exp2 = new class_field_reference(ce.field, new this_node(ce.cont_type, null), null); + else + AddError(get_location(_method_call), "EVENT_{0}_MUST_BE_IN_LEFT_PART", nser.en.name); + } + else if (exp2 is static_event_reference) + { + static_event_reference nser = exp2 as static_event_reference; + common_event ce = nser.en as common_event; + if (ce != null) + exp2 = new static_class_field_reference(ce.field, null); + else if (nser.en is common_namespace_event && _compiled_unit.namespaces.IndexOf((nser.en as common_namespace_event).namespace_node) != -1) + exp2 = new namespace_variable_reference((nser.en as common_namespace_event).field, null); + else + AddError(get_location(_method_call), "EVENT_{0}_MUST_BE_IN_LEFT_PART", nser.en.name); + } + delegate_internal_interface dii = ii as delegate_internal_interface; + sil = new List { new SymbolInfo(dii.invoke_method) }; + } + } + + if (to_type != null) + { + if ((_method_call.parameters == null) || (_method_call.parameters.expressions.Count != 1)) + { + AddError(get_location(_method_call), "ONLY_ONE_PARAMETER_OF_TYPE_CONVERSION_ALLOWED"); + } + if (proc_wait && to_type.IsDelegate) + { + var mc = new SyntaxTree.method_call(new SyntaxTree.expression_list()); + mc.dereferencing_value = _method_call; + procedure_wait = true; + visit(mc); + return; + } + } + + if (_method_call.parameters != null) + { + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) + { + bool tmp = is_format_allowed; + + #region Отмечаем флаг в лямбдах, говорящий о том, что в первый раз будем их "обходить" для вывода типов + //lroman// + if (en is SyntaxTree.function_lambda_definition) + { + lambdas_are_in_parameters = true; + ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode .VisitForInitialMethodCallProcessing; + } + //lroman// + #endregion + + expression_node sem_en = convert_strong(en); + exprs.AddElement(sem_en); + is_format_allowed = tmp; + } + if (SystemLibrary.SystemLibInitializer.AssertProcedure != null && SystemLibrary.SystemLibInitializer.AssertProcedure.Equal(sil) && _method_call.source_context != null) + { + exprs.AddElement(new string_const_node(_method_call.source_context.FileName, null)); + exprs.AddElement(new int_const_node(_method_call.source_context.begin_position.line_num, null)); + } + } + is_format_allowed = false; + CheckSpecialFunctionCall(sil, exprs, get_location(_method_call)); + + sil.RemoveRange(1, sil.Count() - 1); + sil.AddRange(sibak); + + if (to_type != null) + { + //(ssyy) К вызову функции здесь явно не приводим, т.к. это излишне. + expression_node ee = exprs[0]; + bool del = to_type is common_type_node && (to_type as common_type_node).IsDelegate; + + if (!del) + try_convert_typed_expression_to_function_call(ref ee); + else + ee = convert_strong(_method_call.parameters.expressions[0]); + + expr_node = convertion_data_and_alghoritms.explicit_convert_type(ee, to_type); + + //expression_node expr = convert_if_typed_expression_to_function_call(exprs[0]); + //expr_node = convertion_data_and_alghoritms.explicit_convert_type(expr, to_type); + } + else + { + #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим + //lroman// + if (lambdas_are_in_parameters) + { + LambdaHelper.processingLambdaParametersForTypeInference++; + var sil2 = sil; + location mcloc = get_location(_method_call); + if (iwt != null) + { + sil2 = get_generic_functions(sil, true, mcloc); + sil2 = get_function_instances(sil2, iwt.template_params.params_list, id.name, mcloc, sil2.Count() <= 1); + } + // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями + List spf = null; + try + { + function_node fn = convertion_data_and_alghoritms.select_function(exprs, sil2, subloc2, syntax_nodes_parameters); + int exprCounter = 0; + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + exprCounter++; + continue; + } + else + { + var enLambda = (SyntaxTree.function_lambda_definition)en; + if (fn.parameters[exprCounter].is_params) + LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type.element_type, enLambda, this); + else + LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type, enLambda, this); + enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; + exprs[exprCounter] = convert_strong(en); + enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; + exprCounter++; + } + } + } + catch (SeveralFunctionsCanBeCalled sf) + { + spf = sf.set_of_possible_functions; // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна + } + + Exception lastmultex = null; + if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try + { // exprs - глобальная, поэтому надо копировать + int spfnum = -1; // первый номер правильно инстанцированной. Если потом встретился второй, то тоже ошибка + // SSM 4.08.15. Сейчас меняю эту логику. Если будет много кандидатов, но ровно один с совпадающим типом возвращаемого значения, то его и надо выбирать. + // не забыть, что аналогичный код есть в create_constructor_call!!!!!!! И еще выше по коду!!! кошмар!!! + int GoodVersionsCount = 0; + int GoodVersionsCountWithSameResType = 0; + for (int i = 0; i < spf.Count; i++) // цикл по версиям + { + function_node fn = spf[i]; + try // внутренний try регенерирует исключение, а этот гасит + { + int exprCounter = 0; + expressions_list exprs1 = new expressions_list(); + exprs1.AddRange(exprs); // сделали копию + + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + exprCounter++; + continue; + } + else + { + var fld = en as SyntaxTree.function_lambda_definition; + + var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо + var fl = fld.lambda_visit_mode; + + // запомнили типы параметров лямбды - SSM + var cnt = fld.formal_parameters?.params_list?.Count ?? 0; // SSM 22.06.19 + object[] realparamstype = new object[cnt]; // здесь хранятся выведенные типы лямбд или null если типы явно заданы + for (var k = 0; k < cnt; k++) + { + var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; + if (laminftypeK == null) + realparamstype[k] = null; + else realparamstype[k] = laminftypeK.real_type; + } + + // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим + var restype = fld.return_type as SyntaxTree.lambda_inferred_type; + object realrestype = null; + if (restype != null) + realrestype = restype.real_type; + + LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type, fld, this); + fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //lroman + fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! + + //contextChanger.SaveContextAndUpToNearestDefSect(); + try + { + exprs1[exprCounter] = convert_strong(en); + + // SSM 7/08/15 + + type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; + type_node resformaltype = fld.RealSemTypeOfResult as type_node; + var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность + if (bbb) + { + GoodVersionsCountWithSameResType += 1; + spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. + } + + /*var tt = fn.parameters[exprCounter].type as compiled_type_node; + if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) + { + resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func - тип возвращаемого значения + var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность + if (bbb) + { + GoodVersionsCountWithSameResType += 1; + spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. + } + }*/ + } + catch + { + throw; + } + finally + { + LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); + // восстанавливаем сохраненный тип возвращаемого значения + if (restype != null) + restype.real_type = realrestype; + // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно + for (var k = 0; k < (fld.formal_parameters?.params_list?.Count ?? 0); k++) + { + var laminftypeK = fld.formal_parameters.params_list[k].vars_type as SyntaxTree.lambda_inferred_type; + if (laminftypeK != null) + laminftypeK.real_type = realparamstype[k]; + } + + fld.lambda_name = lambdaName; //lroman Восстанавливаем имена + fld.lambda_visit_mode = fl; + } + + //contextChanger.RestoreCurrentContext(); + exprCounter++; + } + } + /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так + { + spfnum = -2; + break; + }*/ + + if (GoodVersionsCountWithSameResType == 0) + spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения + GoodVersionsCount += 1; + for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо + exprs[j] = exprs1[j]; + } + catch (Exception e) + { + // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать + //contextChanger.RestoreCurrentContext(); + lastmultex = e; + } + } //--------------- конец цикла по версиям + + if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения + throw new SeveralFunctionsCanBeCalled(subloc2, spf); + if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд + { + throw lastmultex; + //throw new NoFunctionWithSameArguments(subloc2, false); + } + + var kk = 0; + foreach (SyntaxTree.expression en in _method_call.parameters.expressions) //lroman окончательно подставить типы в лямбды + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + kk++; + continue; + } + else + { + LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, en as SyntaxTree.function_lambda_definition, this); + exprs[kk] = convert_strong(en); + kk++; + } + } + } + // SSM 21.05.14 end + LambdaHelper.processingLambdaParametersForTypeInference--; + } + //lroman// + #endregion + if (exp2 == null) + { + location mcloc = get_location(_method_call); + if (iwt != null) + { + sil = get_generic_functions(sil, true, mcloc); + sil = get_function_instances(sil, iwt.template_params.params_list, id.name, mcloc, sil.Count() <= 1); + } + + + + // #2180 - в уникальной ситуации, когда из метода потомка вызывается метод расширения класса-предка добавлять Self (!) + // Это значит, что dereferencing_value - это идентификатор и sil состоит только (?) из методов расширения + // Надо разделить на две части - для методов расширения добавлять Self. а для не методов - не добавлять + // В первом случае окаймить всё try catch и погашать исключение + if (_method_call.dereferencing_value is ident) + { + var silNoExt = sil.Select(s => s.sym_info).Where(s => s is function_node fn && !fn.is_extension_method).ToList(); + var silExt = sil.Select(s => s.sym_info).Where(s => s is function_node fn && fn.is_extension_method).ToList(); + + if (silNoExt.Count > 0) + { + try + { + expr_node = convertion_data_and_alghoritms.create_full_function_call(exprs, sil, mcloc, + context.converted_type, context.top_function, proc_wait, _method_call.parameters?.expressions); + } + catch (Exception e) + { + if (e is CompilationErrorWithLocation && (e as CompilationErrorWithLocation).loc == null) + (e as CompilationErrorWithLocation).loc = mcloc; + if (silExt.Count == 0) + throw; // не проверять в методах расширения, поскольку их нет + } + + } + // Сюда мы пришли либо с expr_node != null и тогда в методах расширения искать не надо даже если они есть + // либо с expr_node == null и тогда всё будет определяться методами расширения + if (silExt.Count > 0 && expr_node == null) + { + var en0 = convert_strong(new ident("Self",_method_call.dereferencing_value.source_context)); + exprs.AddElementFirst(en0); + expr_node = convertion_data_and_alghoritms.create_full_function_call(exprs, sil, mcloc, + context.converted_type, context.top_function, proc_wait, _method_call.parameters?.expressions); + } + } + else + expr_node = convertion_data_and_alghoritms.create_full_function_call(exprs, sil, mcloc, + context.converted_type, context.top_function, proc_wait, _method_call.parameters?.expressions); + } + else + { + function_node fn = convertion_data_and_alghoritms.select_function(exprs, sil, subloc2, syntax_nodes_parameters); + base_function_call bbffcc = create_not_static_method_call(fn, exp2, subloc2, proc_wait); + bbffcc.parameters.AddRange(exprs); + expr_node = bbffcc; + } + } + + /*if ((proc_wait==false)&&(expr_node.type==null)) + { + throw new FunctionExpectedProcedureMeet((function_node)dn,get_location(_method_call)); + }*/ + + visit_mc_helper(mot, expr_node, expr_node.location, exprs, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO",true); + return; + + + /*switch (mot) + { + case motivation.expression_evaluation: + { + return_value(expr_node); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(expr_node); + return; + } + case motivation.address_receiving: + { + AddError(get_location(_method_call), "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); + return; + } + default: + { + //throw new CompilerInternalError("Can not recive address from method call");//! + AddError(get_location(_method_call), "EXPECTED_VARIABLE"); + return; + } + }*/ + //throw new CompilerInternalError("Error in creation method call"); + + } + + //remove extension methods when static methods called + private void delete_extension_methods(ref List sil, type_node tn) + { + List si_list = new List(); + if (sil != null) + { + foreach (SymbolInfo si in sil) + { + var fn = si.sym_info as function_node; + if (fn != null) + { + if (fn.is_extension_method) + { + compiled_function_node cfn = fn as compiled_function_node; + if (cfn != null && cfn.cont_type == tn) + si_list.Add(si); + } + else + si_list.Add(si); + } + else + si_list.Add(si); + /*if (!(fn != null && fn.is_extension_method)) + si_list.Add(tmp_si);*/ + } + sil = si_list; + if(si_list.Count == 0) + sil = null; + } + /*tmp_si = si; + while (tmp_si != null) + { + var fn = tmp_si.sym_info as function_node; + if (fn != null && fn.is_extension_method) + { + var b = false; + foreach (var x in si_list) + { + var xn = x.sym_info as function_node; + if (convertion_data_and_alghoritms.function_eq_params(fn, xn)) + { + b = true; + break; + } + } + if (!b) + si_list.Add(tmp_si); + } + tmp_si = tmp_si.Next; + }*/ + } + + //ssyy + //Удаляет конструкторы предков в списке si + private void delete_inherited_constructors(ref List si, type_node tn) + { + int cur_ind = 0; + while (si!= null && cur_ind < si.Count()) + { + type_node comph_type = null; + bool is_ctor = false; + common_method_node mnode = si[cur_ind].sym_info as common_method_node; + if (mnode != null) + { + comph_type = mnode.cont_type; + is_ctor = mnode.is_constructor; + } + else + { + compiled_function_node tnode = si[cur_ind].sym_info as compiled_function_node; + if (tnode != null) + { + comph_type = tnode.cont_type; + is_ctor = tnode.method_info.IsConstructor; + } + } + //Итак, comph_type - класс, содержащий si.sym_info; + //is_ctor - является ли оно конструктором + if (is_ctor && comph_type != tn) + { + //Удаляем + si.RemoveAt(cur_ind); + } + else + ++cur_ind; + } + if (si != null && si.FirstOrDefault() == null) + si = null; + } + //\ssyy + + //TODO: Возможно следует переписать этот метод в более простой форме. + public override void visit(SyntaxTree.method_call _method_call) + { + visit_method_call(_method_call); + inherited_ident_processing = false; + } + + private void ConvertPointersForWrite(expressions_list exprs) + { + for (int i = 0; i < exprs.Count; ++i) + { + if (exprs[i].type.IsPointer) + { + if (SystemLibrary.SystemLibInitializer.PointerOutputConstructor == null) + { + List sil = (SystemLibrary.SystemLibInitializer.PointerOutputType.sym_info as common_type_node).find_in_type(compiler_string_consts.default_constructor_name); + common_method_node cnode = null; + int cur_si_ind = 0; + do + { + cnode = sil[cur_si_ind].sym_info as common_method_node; + if (cnode.parameters.Count != 1) + { + cnode = null; + ++cur_si_ind; + } + } + while (cnode == null); + SystemLibrary.SystemLibInitializer.PointerOutputConstructor = cnode; + } + common_constructor_call cnc = new common_constructor_call(SystemLibrary.SystemLibInitializer.PointerOutputConstructor as common_method_node, exprs[i].location); + //common_namespace_function_call cnfc = new common_namespace_function_call( + // SystemLibrary.SystemLibInitializer.PointerToStringFunction.sym_info as common_namespace_function_node, + // exprs[i].location); + cnc.parameters.AddElement(exprs[i]); + exprs[i] = cnc; + } + } + } + + private void ConvertPointersForWriteFromDll(expressions_list exprs) + { + for (int i = 0; i < exprs.Count; ++i) + { + if (exprs[i].type.IsPointer) + { + if (SystemLibrary.SystemLibInitializer.PointerOutputConstructor == null) + { + List sil = (SystemLibrary.SystemLibInitializer.PointerOutputType.sym_info as compiled_type_node).find_in_type(compiler_string_consts.default_constructor_name); + compiled_constructor_node cnode = null; + int cur_si_index = 0; + do + { + cnode = sil[cur_si_index].sym_info as compiled_constructor_node; + if (cnode.parameters.Count != 1) + { + cnode = null; + ++cur_si_index; + } + } + while (cnode == null); + SystemLibrary.SystemLibInitializer.PointerOutputConstructor = cnode; + } + compiled_constructor_call cnc = new compiled_constructor_call(SystemLibrary.SystemLibInitializer.PointerOutputConstructor as compiled_constructor_node, exprs[i].location); + //common_namespace_function_call cnfc = new common_namespace_function_call( + // SystemLibrary.SystemLibInitializer.PointerToStringFunction.sym_info as common_namespace_function_node, + // exprs[i].location); + cnc.parameters.AddElement(exprs[i]); + exprs[i] = cnc; + } + } + } + + private void CheckSpecialFunctionCall(List sil, expressions_list exprs, location loc) + { + if (SystemUnitAssigned) + { + bool write_proc = SystemLibrary.SystemLibInitializer.write_procedure.Equal(sil); + if (write_proc && exprs.Count > 1) + { + //возможно это запись в типизированый файл + if (exprs[0].type.type_special_kind == SemanticTree.type_special_kind.typed_file) + //да, точно это типизированый файл! + { + //Проверим типы параметров вызова на совпадение с типом элементов файла + type_node element_type = exprs[0].type.element_type; + for (int i = 1; i < exprs.Count; i++) + convertion_data_and_alghoritms.check_convert_type(exprs[i], element_type, exprs[i].location); + if (element_type.type_special_kind == SemanticTree.type_special_kind.short_string) + { + for (int i = 1; i < exprs.Count; i++) + { + //common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node,null); + //cmc.parameters.AddElement(exprs[i]); + //cmc.parameters.AddElement(new int_const_node((element_type as short_string_type_node).Length,null)); + expression_node cmc = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node, null, convertion_data_and_alghoritms.convert_type(exprs[i], SystemLibrary.SystemLibrary.string_type), new int_const_node((element_type as short_string_type_node).Length, null)); + exprs[i] = cmc; + } + } + //if (exprs[i].type != element_type) + // throw new ExpectedExprHaveTypeTypedFile(element_type, exprs[i].type, false, get_location(_method_call.parameters.expressions[i])); + } + else + //(ssyy) а может быть, в бинарный! + if (exprs[0].type.type_special_kind == SemanticTree.type_special_kind.binary_file) + { + //(ssyy) действительно, бинарный + for (int i = 1; i < exprs.Count; i++) + { + if (!CanUseThisTypeForBinaryFiles(exprs[i].type)) + { + AddError(exprs[i].location, "CAN_NOT_WRITE_REFERENCE_DATA_TO_BINARY_FILE"); + } + } + } + else + { + if (SystemLibrary.SystemLibInitializer.write_procedure.sym_info is common_namespace_function_node) + ConvertPointersForWrite(exprs); + else + ConvertPointersForWriteFromDll(exprs); + } + } + else if (write_proc || SystemLibrary.SystemLibInitializer.writeln_procedure.Equal(sil)) + { + //(ssyy) Преобразуем указатели в строки для вывода write/writeln + if (SystemLibrary.SystemLibInitializer.writeln_procedure.sym_info is common_namespace_function_node) + ConvertPointersForWrite(exprs); + else + ConvertPointersForWriteFromDll(exprs); + } + else if (SystemLibrary.SystemLibInitializer.IncludeProcedure.Equal(sil) + || SystemLibrary.SystemLibInitializer.ExcludeProcedure.Equal(sil)) + { + if (exprs.Count != 2) AddError(new NoFunctionWithSameArguments(loc, true)); + type_node element_type = exprs[0].type.element_type; + if (exprs[0].type.type_special_kind != SemanticTree.type_special_kind.base_set_type && exprs[0].type.type_special_kind != SemanticTree.type_special_kind.set_type) + { + AddError(new NoFunctionWithSameArguments(loc, true)); + } + if (element_type != null) + convertion_data_and_alghoritms.check_convert_type(exprs[1], element_type, exprs[1].location); + else convertion_data_and_alghoritms.check_convert_type(exprs[1], exprs[0].type, exprs[0].location); + if (!exprs[0].is_addressed) AddError(new ThisExpressionCanNotBePassedAsVarParameter(exprs[0])); + } + else if (SystemLibrary.SystemLibInitializer.InSetProcedure.Equal(sil)) + { + if (exprs.Count != 2) AddError(new NoFunctionWithSameArguments(loc, true)); + type_node element_type = exprs[1].type.element_type; + if (element_type != null) + { + //exprs[0] = convertion_data_and_alghoritms.convert_type(exprs[0], element_type, exprs[0].location); + convertion_data_and_alghoritms.check_convert_type(exprs[0], element_type, exprs[0].location); + } + else convertion_data_and_alghoritms.check_convert_type(exprs[0], exprs[1].type, exprs[0].location); + } + else if (SystemLibrary.SystemLibInitializer.SetUnionProcedure.Equal(sil) + || SystemLibrary.SystemLibInitializer.SetIntersectProcedure.Equal(sil) || SystemLibrary.SystemLibInitializer.SetSubtractProcedure.Equal(sil)) + { + if (exprs.Count != 2) AddError(new NoFunctionWithSameArguments(loc, true)); + convertion_data_and_alghoritms.check_convert_type(exprs[1], exprs[0].type, exprs[1].location); + } + + if (sil.FirstOrDefault() == SystemLibrary.SystemLibInitializer.NewProcedure || sil.FirstOrDefault() == SystemLibrary.SystemLibInitializer.DisposeProcedure) + { + if (exprs[0].type == SystemLibrary.SystemLibrary.pointer_type) + AddError(exprs[0].location, "EXPECTED_TYPED_POINTER_IN_PROCEDURE{0}", (sil.FirstOrDefault().sym_info as function_node).name); + } + } + } + + private expression_node make_new_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc) + { + if (parameters == null) AddError( new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node)); + if (parameters.expressions.Count == 1) + { + expression_node param0 = convert_strong(parameters.expressions[0]); + if (!param0.type.IsPointer || param0.type == SystemLibrary.SystemLibrary.pointer_type) + AddError(new NoFunctionWithSameArguments(loc, true)); + if (!param0.is_addressed) + { + bool is_pascal_array_ref = false; + if (param0.semantic_node_type == semantic_node_type.common_method_call) + { + common_method_call cmc = (common_method_call)param0; + internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); + if (ii != null) + { + if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) + { + bounded_array_interface bai = (bounded_array_interface)ii; + class_field cf = bai.int_array; + expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); + expression_node right = cmc.parameters[0]; + //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); + right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); + right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, + new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); + param0 = new simple_array_indexing(left, right, cmc.type, cmc.location); + is_pascal_array_ref = true; + } + } + if (!is_pascal_array_ref) + { + AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); + } + + } + else AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); + } + if (param0.type is ref_type_node && !can_evaluate_size((param0.type as ref_type_node).pointed_type)) + AddError(loc, "CANNOT_CALL_NEW_BECAUSE_OF_UNDEFINED_SIZE"); + function_node fn = si.sym_info as function_node; + common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); + cnfc.parameters.AddElement(param0); + return cnfc; + + } + else + { + AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node)); + return null; + } + } + + private expression_node make_dispose_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc) + { + if (parameters == null) + { + AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node)); + return null; + } + if (parameters.expressions.Count == 1) + { + expression_node param0 = convert_strong(parameters.expressions[0]); + if (!param0.type.IsPointer || param0.type == SystemLibrary.SystemLibrary.pointer_type) + AddError(new NoFunctionWithSameArguments(loc, true)); + if (!param0.is_addressed) + { + bool is_pascal_array_ref = false; + if (param0.semantic_node_type == semantic_node_type.common_method_call) + { + common_method_call cmc = (common_method_call)param0; + internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); + if (ii != null) + { + if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) + { + bounded_array_interface bai = (bounded_array_interface)ii; + class_field cf = bai.int_array; + expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); + expression_node right = cmc.parameters[0]; + //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); + right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); + right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, + new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); + param0 = new simple_array_indexing(left, right, cmc.type, cmc.location); + is_pascal_array_ref = true; + } + } + if (!is_pascal_array_ref) + { + AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); + return null; + } + + } + else + { + AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); + return null; + } + } + function_node fn = si.sym_info as function_node; + common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); + cnfc.parameters.AddElement(param0); + return cnfc; + + } + else + { + AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node)); + return null; + } + } + + private expression_node make_ord_call(List sil, SyntaxTree.expression_list parameters, location loc) + { + if (parameters == null) + { + AddError(new NoFunctionWithSameParametresNum(loc, false, sil.FirstOrDefault().sym_info as function_node)); + return null; + } + if (parameters.expressions.Count == 1) + { + expression_node param0 = convert_strong(parameters.expressions[0]); + if (param0 is typed_expression) param0 = convert_typed_expression_to_function_call(param0 as typed_expression); + + expressions_list el = new expressions_list(); + el.AddElement(param0); + function_node fn = null; + try + { + fn = convertion_data_and_alghoritms.select_function(el, sil, loc); + } + catch (Exception e) + { + + } + if (fn != null) + { + if (fn is common_namespace_function_node) + { + common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); + cnfc.parameters.AddElement(param0); + return cnfc; + } + else + { + compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc); + cnfc.parameters.AddElement(param0); + return cnfc; + } + } + else if (param0.type.IsEnum || param0.type.type_special_kind == SemanticTree.type_special_kind.diap_type) + { + el = new expressions_list(); + el.AddElement(new int_const_node(1, null)); + fn = convertion_data_and_alghoritms.select_function(el, sil, loc); + //bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); + //bfc.ret_type = param0.type; + if (fn is common_namespace_function_node) + { + common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); + cnfc.parameters.AddElement(param0); + return cnfc; + } + else + { + compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc); + cnfc.parameters.AddElement(param0); + return cnfc; + } + } + + else + { + AddError(new NoFunctionWithSameArguments(loc, false)); + return null; + } + } + else + { + AddError(new NoFunctionWithSameParametresNum(loc, false, sil.FirstOrDefault().sym_info as function_node)); + return null; + } + } + + private expression_node make_succ_call(List sil, SyntaxTree.expression_list parameters, location loc) + { + if (parameters == null) + { + AddError(new NoFunctionWithSameParametresNum(loc, false, sil.FirstOrDefault().sym_info as function_node)); + return null; + } + if (parameters.expressions.Count == 1) + { + expression_node param0 = convert_strong(parameters.expressions[0]); + if (param0 is typed_expression) param0 = convert_typed_expression_to_function_call(param0 as typed_expression); + basic_function_call bfc = null; + int type_flag = 0; + expressions_list el = new expressions_list(); + el.AddElement(param0); + function_node fn = null; + try + { + fn = convertion_data_and_alghoritms.select_function(el,sil,loc); + } + catch(Exception e) + { + + } + if (fn != null) + { + if (fn is common_namespace_function_node) + { + common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); + cnfc.parameters.AddElement(param0); + return cnfc; + } + else + { + compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc); + cnfc.parameters.AddElement(param0); + return cnfc; + } + } + if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || param0.type.IsEnum) + { + el = new expressions_list(); + el.AddElement(new int_const_node(1,null)); + fn = convertion_data_and_alghoritms.select_function(el,sil,loc); + //bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); + //bfc.ret_type = param0.type; + if (fn is common_namespace_function_node) + { + common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); + cnfc.parameters.AddElement(param0); + cnfc.type = param0.type; + return cnfc; + } + else + { + compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc); + cnfc.parameters.AddElement(param0); + cnfc.type = param0.type; + return cnfc; + } + } + else AddError(new NoFunctionWithSameArguments(loc,false)); + bfc.parameters.AddElement(param0); + if (type_flag == 0 || type_flag == 3) + bfc.parameters.AddElement(new int_const_node(1,null)); + else if (type_flag == 1) + bfc.parameters.AddElement(new long_const_node(1,null)); + else if (type_flag == 2) + bfc.parameters.AddElement(new ulong_const_node(1,null)); + return bfc; + } + AddError(new NoFunctionWithSameParametresNum(loc,false,sil.FirstOrDefault().sym_info as function_node)); + return null; + } + + private expression_node make_pred_call(List sil, SyntaxTree.expression_list parameters, location loc) + { + if (parameters == null) + { + AddError(new NoFunctionWithSameParametresNum(loc, false, sil.FirstOrDefault().sym_info as function_node)); + return null; + } + if (parameters.expressions.Count == 1) + { + expression_node param0 = convert_strong(parameters.expressions[0]); + if (param0 is typed_expression) param0 = convert_typed_expression_to_function_call(param0 as typed_expression); + basic_function_call bfc = null; + int type_flag = 0; + expressions_list el = new expressions_list(); + el.AddElement(param0); + function_node fn = null; + try + { + fn = convertion_data_and_alghoritms.select_function(el,sil,loc); + } + catch(Exception e) + { + + } + if (fn != null) + { + if (fn is common_namespace_function_node) + { + common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); + cnfc.parameters.AddElement(param0); + return cnfc; + } + else + { + compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc); + cnfc.parameters.AddElement(param0); + return cnfc; + } + } + else if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || param0.type.IsEnum) + { + el = new expressions_list(); + el.AddElement(new int_const_node(1,null)); + fn = convertion_data_and_alghoritms.select_function(el,sil,loc); + //bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); + //bfc.ret_type = param0.type; + if (fn is common_namespace_function_node) + { + common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node, loc); + cnfc.parameters.AddElement(param0); + cnfc.type = param0.type; + return cnfc; + } + else + { + compiled_static_method_call cnfc = new compiled_static_method_call(fn as compiled_function_node, loc); + cnfc.parameters.AddElement(param0); + cnfc.type = param0.type; + return cnfc; + } + } + else AddError(new NoFunctionWithSameArguments(loc,false)); + bfc.parameters.AddElement(param0); + if (type_flag == 0 || type_flag == 3) + bfc.parameters.AddElement(new int_const_node(1,null)); + else if (type_flag == 1) + bfc.parameters.AddElement(new long_const_node(1,null)); + else if (type_flag == 2) + bfc.parameters.AddElement(new ulong_const_node(1,null)); + return bfc; + } + AddError(new NoFunctionWithSameParametresNum(loc,false,sil.FirstOrDefault().sym_info as function_node)); + return null; + } + + private expression_node make_inc_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc) + { + if (parameters == null) + { + AddError(new NoFunctionWithSameParametresNum(loc, false, si.sym_info as function_node)); + return null; + } + if (parameters.expressions.Count == 1 || parameters.expressions.Count == 2) + { + expression_node param0 = convert_strong(parameters.expressions[0]); + if (!param0.is_addressed) + { + bool is_pascal_array_ref = false; + if (param0.semantic_node_type == semantic_node_type.common_method_call) + { + common_method_call cmc = (common_method_call)param0; + internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); + if (ii != null) + { + if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) + { + bounded_array_interface bai = (bounded_array_interface)ii; + class_field cf = bai.int_array; + expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); + expression_node right = cmc.parameters[0]; + //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); + right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); + right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, + new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); + param0 = new simple_array_indexing(left, right, cmc.type, cmc.location); + is_pascal_array_ref = true; + } + } + if (!is_pascal_array_ref) + { + AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); + } + + } + else if (param0 is compiled_function_call) + { + compiled_function_call cfc = param0 as compiled_function_call; + if ((cfc.function_node.return_value_type == SystemLibrary.SystemLibrary.char_type && cfc.function_node.cont_type == SystemLibrary.SystemLibrary.string_type + && cfc.function_node == cfc.function_node.cont_type.default_property_node.get_function)) + { + expressions_list exl = new expressions_list(); + exl.AddElement(cfc.obj); + exl.AddElement(cfc.parameters[0]); + basic_function_call bfc2 = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); + bfc2.parameters.AddElement(param0); + expression_node _param1 = null; + if (parameters.expressions.Count == 2) + { + _param1 = convert_strong(parameters.expressions[1]); + } + if (_param1 != null) + bfc2.parameters.AddElement(convertion_data_and_alghoritms.convert_type(_param1,SystemLibrary.SystemLibrary.integer_type)); + else + bfc2.parameters.AddElement(new int_const_node(1,null)); + expressions_list el = new expressions_list(); + el.AddElement(convertion_data_and_alghoritms.convert_type(bfc2,SystemLibrary.SystemLibrary.ushort_type)); + function_node chr_func = convertion_data_and_alghoritms.select_function(el, SystemLibrary.SystemLibInitializer.ChrUnicodeFunction.SymbolInfo, loc); + exl.AddElement(convertion_data_and_alghoritms.create_simple_function_call(chr_func, loc, el.ToArray())); + function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure.SymbolInfo, loc); + expression_node ret = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, exl.ToArray()); + return ret; + } + else + { + AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); + } + } + else AddError(new ThisExpressionCanNotBePassedAsVarParameter(param0)); + } + else + check_on_loop_variable(param0); + expression_node param1 = null; + int type_flag = 0; + bool is_uint = false; + bool is_enum = false; + if (parameters.expressions.Count == 2) + { + param1 = convert_strong(parameters.expressions[1]); + //param1 = convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type); + } + basic_function_call ass = null; + basic_function_call bfc = null; + if (param0.type == SystemLibrary.SystemLibrary.integer_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); + } + else if (param0.type == SystemLibrary.SystemLibrary.char_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.char_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); + } + else if (param0.type == SystemLibrary.SystemLibrary.byte_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.byte_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); + } + else if (param0.type == SystemLibrary.SystemLibrary.sbyte_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.sbyte_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); + } + else if (param0.type == SystemLibrary.SystemLibrary.short_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.short_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); + } + else if (param0.type == SystemLibrary.SystemLibrary.ushort_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.ushort_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); + } + else if (param0.type == SystemLibrary.SystemLibrary.uint_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.uint_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.uint_add as basic_function_node,loc); + type_flag = 2; + is_uint = true; + } + else if (param0.type == SystemLibrary.SystemLibrary.int64_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.long_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.long_add as basic_function_node,loc); + type_flag = 1; + } + else if (param0.type == SystemLibrary.SystemLibrary.uint64_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.ulong_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.ulong_add as basic_function_node,loc); + type_flag = 2; + } + else if (param0.type == SystemLibrary.SystemLibrary.bool_type) + { + if (param1 == null) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc); + type_flag = 4; + } + else + { + basic_function_call mod_expr = new basic_function_call(SystemLibrary.SystemLibrary.int_mod as basic_function_node,loc); + mod_expr.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type)); + mod_expr.parameters.AddElement(new int_const_node(2,loc)); + basic_function_call condition = new basic_function_call(SystemLibrary.SystemLibrary.int_eq as basic_function_node,loc); + condition.parameters.AddElement(mod_expr); + condition.parameters.AddElement(new int_const_node(0,loc)); + basic_function_call not_expr = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc); + not_expr.parameters.AddElement(param0); + question_colon_expression qce = new question_colon_expression(condition, param0, not_expr, loc); + ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc); + ass.parameters.AddElement(param0); + ass.parameters.AddElement(qce); + type_flag = 5; + } + } + else if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || param0.type.IsEnum) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_add as basic_function_node,loc); + if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) + { + type_node bt = param0.type.base_type; + if (bt == SystemLibrary.SystemLibrary.int64_type) type_flag = 1; + else if (bt == SystemLibrary.SystemLibrary.uint64_type) type_flag = 2; + else if (bt == SystemLibrary.SystemLibrary.uint_type) + { + type_flag =2; + is_uint = true; + } + else if (bt.IsEnum) + { + is_enum = true; + } + } + else if (param0.type.IsEnum) is_enum = true; + } + else AddError(new NoFunctionWithSameArguments(loc,false)); + if (type_flag != 5) + { + if (param1 != null) + switch (type_flag) + { + case 0: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.integer_type); break; + case 3: + case 1: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.int64_type); break; + case 2: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.uint64_type); break; + } + if (param0.type != SystemLibrary.SystemLibrary.char_type && !is_enum && param0.type != SystemLibrary.SystemLibrary.bool_type) + switch (type_flag) + { + case 0: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.integer_type)); break; + case 3: + case 1: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.int64_type)); break; + case 2: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.uint64_type)); break; + } + + else bfc.parameters.AddElement(param0); + //bfc.parameters.AddElement(param0); + + if (param1 == null) + { + if (type_flag == 0 || type_flag == 3) + bfc.parameters.AddElement(new int_const_node(1, null)); + else if (type_flag == 1) + bfc.parameters.AddElement(new long_const_node(1, null)); + else if (type_flag == 2) + bfc.parameters.AddElement(new ulong_const_node(1, null)); + } + else + bfc.parameters.AddElement(param1); + ass.parameters.AddElement(param0); + if (is_uint) + ass.parameters.AddElement(convertion_data_and_alghoritms.convert_type(bfc, SystemLibrary.SystemLibrary.uint_type)); + else + if (param0.type == SystemLibrary.SystemLibrary.char_type) + { + expressions_list el = new expressions_list(); + el.AddElement(convertion_data_and_alghoritms.convert_type(bfc, SystemLibrary.SystemLibrary.ushort_type)); + function_node chr_func = convertion_data_and_alghoritms.select_function(el, SystemLibrary.SystemLibInitializer.ChrUnicodeFunction.SymbolInfo, loc); + ass.parameters.AddElement(convertion_data_and_alghoritms.create_simple_function_call(chr_func, loc, el.ToArray())); + } + else + ass.parameters.AddElement(bfc); + } + return ass; + } + + AddError(new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node)); + return null; + } + + private expression_node make_dec_call(SymbolInfo si, SyntaxTree.expression_list parameters, location loc) + { + if (parameters == null) throw new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node); + if (parameters.expressions.Count == 1 || parameters.expressions.Count == 2) + { + expression_node param0 = convert_strong(parameters.expressions[0]); + if (!param0.is_addressed) + { + bool is_pascal_array_ref = false; + if (param0.semantic_node_type == semantic_node_type.common_method_call) + { + common_method_call cmc = (common_method_call)param0; + internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); + if (ii != null) + { + if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) + { + bounded_array_interface bai = (bounded_array_interface)ii; + class_field cf = bai.int_array; + expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); + expression_node right = cmc.parameters[0]; + //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); + right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); + right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, + new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); + param0 = new simple_array_indexing(left, right, cmc.type, cmc.location); + is_pascal_array_ref = true; + + } + } + if (!is_pascal_array_ref) + { + throw new ThisExpressionCanNotBePassedAsVarParameter(param0); + } + + } + else if (param0 is compiled_function_call) + { + compiled_function_call cfc = param0 as compiled_function_call; + if ((cfc.function_node.return_value_type == SystemLibrary.SystemLibrary.char_type && cfc.function_node.cont_type == SystemLibrary.SystemLibrary.string_type + && cfc.function_node == cfc.function_node.cont_type.default_property_node.get_function)) + { + expressions_list exl = new expressions_list(); + exl.AddElement(cfc.obj); + exl.AddElement(cfc.parameters[0]); + basic_function_call bfc2 = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); + bfc2.parameters.AddElement(param0); + expression_node _param1 = null; + if (parameters.expressions.Count == 2) + { + _param1 = convert_strong(parameters.expressions[1]); + } + if (_param1 != null) + bfc2.parameters.AddElement(convertion_data_and_alghoritms.convert_type(_param1,SystemLibrary.SystemLibrary.integer_type)); + else + bfc2.parameters.AddElement(new int_const_node(1,null)); + expressions_list el = new expressions_list(); + el.AddElement(convertion_data_and_alghoritms.convert_type(bfc2,SystemLibrary.SystemLibrary.ushort_type)); + function_node chr_func = convertion_data_and_alghoritms.select_function(el,SystemLibrary.SystemLibInitializer.ChrUnicodeFunction.SymbolInfo, loc); + exl.AddElement(convertion_data_and_alghoritms.create_simple_function_call(chr_func, loc, el.ToArray())); + function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure.SymbolInfo, loc); + expression_node ret = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, exl.ToArray()); + return ret; + } + else + { + throw new ThisExpressionCanNotBePassedAsVarParameter(param0); + } + } + else throw new ThisExpressionCanNotBePassedAsVarParameter(param0); + } + else + check_on_loop_variable(param0); + expression_node param1 = null; + int type_flag = 0; + bool is_uint=false; + bool is_enum=false; + if (parameters.expressions.Count == 2) + { + param1 = convert_strong(parameters.expressions[1]); + param1 = convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type); + } + basic_function_call ass = null; + basic_function_call bfc = null; + if (param0.type == SystemLibrary.SystemLibrary.integer_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); + } + else if (param0.type == SystemLibrary.SystemLibrary.char_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.char_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); + } + else if (param0.type == SystemLibrary.SystemLibrary.byte_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.byte_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); + } + else if (param0.type == SystemLibrary.SystemLibrary.sbyte_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.sbyte_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); + } + else if (param0.type == SystemLibrary.SystemLibrary.short_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.short_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); + } + else if (param0.type == SystemLibrary.SystemLibrary.ushort_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.ushort_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); + } + else if (param0.type == SystemLibrary.SystemLibrary.uint_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.uint_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.uint_sub as basic_function_node,loc); + type_flag = 2; + is_uint = true; + } + else if (param0.type == SystemLibrary.SystemLibrary.int64_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.long_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.long_sub as basic_function_node,loc); + type_flag = 1; + } + else if (param0.type == SystemLibrary.SystemLibrary.uint64_type) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.ulong_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.ulong_sub as basic_function_node,loc); + type_flag = 2; + } + else if (param0.type == SystemLibrary.SystemLibrary.bool_type) + { + if (param1 == null) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc); + type_flag = 4; + } + else + { + basic_function_call mod_expr = new basic_function_call(SystemLibrary.SystemLibrary.int_mod as basic_function_node,loc); + mod_expr.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param1,SystemLibrary.SystemLibrary.integer_type)); + mod_expr.parameters.AddElement(new int_const_node(2,loc)); + basic_function_call condition = new basic_function_call(SystemLibrary.SystemLibrary.int_eq as basic_function_node,loc); + condition.parameters.AddElement(mod_expr); + condition.parameters.AddElement(new int_const_node(0,loc)); + basic_function_call not_expr = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node,loc); + not_expr.parameters.AddElement(param0); + question_colon_expression qce = new question_colon_expression(condition, param0, not_expr, loc); + ass = new basic_function_call(SystemLibrary.SystemLibrary.bool_assign as basic_function_node,loc); + ass.parameters.AddElement(param0); + ass.parameters.AddElement(qce); + type_flag = 5; + } + } + else if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type || param0.type.IsEnum) + { + ass = new basic_function_call(SystemLibrary.SystemLibrary.int_assign as basic_function_node,loc); + bfc = new basic_function_call(SystemLibrary.SystemLibrary.int_sub as basic_function_node,loc); + if (param0.type.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.diap_type) + { + type_node bt = param0.type.base_type; + if (bt == SystemLibrary.SystemLibrary.int64_type) type_flag = 1; + else if (bt == SystemLibrary.SystemLibrary.uint64_type) type_flag = 2; + else if (bt == SystemLibrary.SystemLibrary.uint_type) + { + type_flag =2; + is_uint = true; + } + else if (bt.IsEnum) is_enum = true; + } + else if (param0.type.IsEnum) is_enum = true; + } + else throw new NoFunctionWithSameArguments(loc,false); + if (type_flag != 5) + { + if (param1 != null) + switch (type_flag) + { + case 0: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.integer_type); break; + case 3: + case 1: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.int64_type); break; + case 2: param1 = convertion_data_and_alghoritms.convert_type(param1, SystemLibrary.SystemLibrary.uint64_type); break; + } + //bfc.parameters.AddElement(param0); + if (param0.type != SystemLibrary.SystemLibrary.char_type && !is_enum && param0.type != SystemLibrary.SystemLibrary.bool_type) + switch (type_flag) + { + case 0: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.integer_type)); break; + case 3: + case 1: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.int64_type)); break; + case 2: bfc.parameters.AddElement(convertion_data_and_alghoritms.convert_type(param0, SystemLibrary.SystemLibrary.uint64_type)); break; + } + else bfc.parameters.AddElement(param0); + if (param1 == null) + { + if (type_flag == 0 || type_flag == 3) + bfc.parameters.AddElement(new int_const_node(1, null)); + else if (type_flag == 1) + bfc.parameters.AddElement(new long_const_node(1, null)); + else if (type_flag == 2) + bfc.parameters.AddElement(new ulong_const_node(1, null)); + } + else bfc.parameters.AddElement(param1); + ass.parameters.AddElement(param0); + if (is_uint) + ass.parameters.AddElement(convertion_data_and_alghoritms.convert_type(bfc, SystemLibrary.SystemLibrary.uint_type)); + else + ass.parameters.AddElement(bfc); + } + return ass; + } + + throw new NoFunctionWithSameParametresNum(loc,false,si.sym_info as function_node); + } + + private void check_on_loop_variable(expression_node en) + { + if (context.is_in_cycle() && !SemanticRules.AllowChangeLoopVariable) + if (en.semantic_node_type == semantic_node_type.namespace_variable_reference) + { + if (context.is_loop_variable((en as namespace_variable_reference).var)) + AddError(en.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE"); + } + else if (en.semantic_node_type == semantic_node_type.local_variable_reference) + { + if (context.is_loop_variable((en as local_variable_reference).var)) + AddError(en.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE"); + } + else if (en.semantic_node_type == semantic_node_type.local_block_variable_reference) + { + if (context.is_loop_variable((en as local_block_variable_reference).var)) + AddError(en.location, "CANNOT_ASSIGN_TO_LOOP_VARIABLE"); + } + + } + + private expression_node make_read_call(List sil, SyntaxTree.expression_list parameters, location loc) + { + + // вызов read(a,b,c) разбивается на несколько вызовов, последний возвращается узлом, а остальные добавляются здесь в теле expressions_list exl = new expressions_list(); + expression_node last_call = null; + expressions_list exl = new expressions_list(); + expression_node file = null; + bool read_from_file = false; + bool read_from_text_file = false; + bool read_from_typed_file = false; + bool read_from_binary_file = false; + bool readln_string_file = false; + if (parameters != null) // если список параметров не пуст + { + if (parameters.expressions.Count >= 1) + { + expression_node param0 = convert_strong(parameters.expressions[0]); + if (param0.type != null) + { + if (SystemLibrary.SystemLibInitializer.TextFileType.Found && param0.type == SystemLibrary.SystemLibInitializer.TextFileType.sym_info) + { + file = param0; + read_from_text_file = true; + } + if (param0.type.type_special_kind == SemanticTree.type_special_kind.typed_file + && parameters.expressions.Count > 1 //это можно внести во внутрь + )//и побросать приличные исключения + { + if (!SystemLibrary.SystemLibInitializer.read_procedure.FromDll) + { + if (sil.SequenceEqual(SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo)) + { + file = param0; + read_from_typed_file = true; + } + } + else if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(sil)) + { + file = param0; + read_from_typed_file = true; + } + } + if (param0.type.type_special_kind == SemanticTree.type_special_kind.binary_file + && parameters.expressions.Count > 1 //это можно внести во внутрь + )//и побросать приличные исключения + { + if (!SystemLibrary.SystemLibInitializer.read_procedure.FromDll) + { + if (sil.SequenceEqual(SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo)) + { + file = param0; + read_from_binary_file = true; + } + } + else if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(sil)) + { + file = param0; + read_from_binary_file = true; + } + } + } + read_from_file = read_from_text_file || read_from_typed_file || read_from_binary_file; + } + bool first_iteration = true; + + foreach (SyntaxTree.expression ex in parameters.expressions) + { + if (first_iteration && read_from_file) + { + first_iteration = false; + continue; + } + if (last_call != null && convertion_data_and_alghoritms.statement_list_stack.size > 0) + convertion_data_and_alghoritms.statement_list_stack.top().statements.AddElement(last_call); + expression_node en = convert_strong(ex); + check_on_loop_variable(en); + //if (en.type == null) + //throw new CanNotRead(en.location); + exl.clear(); + if (read_from_file) + exl.AddElement(file); + if (read_from_typed_file) + { + if (SystemLibrary.SystemLibInitializer.TypedFileReadProcedure == null) + AddError(new NotSupportedError(loc)); + if (en.type != file.type.element_type) + AddError(new ExpectedExprHaveTypeTypedFile(file.type.element_type, en.type, true, get_location(ex))); + bool is_char_getter = false; + if (!en.is_addressed) + { + if (en is compiled_function_call) + { + compiled_function_call cfc = en as compiled_function_call; + + if ((cfc.function_node.return_value_type == SystemLibrary.SystemLibrary.char_type && cfc.function_node.cont_type == SystemLibrary.SystemLibrary.string_type + && cfc.function_node == cfc.function_node.cont_type.default_property_node.get_function)) + { + en = new simple_array_indexing((en as compiled_function_call).obj, (en as compiled_function_call).parameters[0], SystemLibrary.SystemLibrary.char_type, en.location); + is_char_getter = true; + } + + } + } + function_node fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.TypedFileReadProcedure.SymbolInfo, loc); + expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), file); + //expression_node expr = convertion_data_and_alghoritms.create_full_function_call(exl, SystemLibrary.SystemLibInitializer.TypedFileReadProcedure.SymbolInfo, loc, context.converted_type, context.top_function, true); + expr = convertion_data_and_alghoritms.explicit_convert_type(expr, file.type.element_type); + if (is_char_getter) + expr = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.StringDefaultPropertySetProcedure.sym_info as function_node, loc, (en as simple_array_indexing).simple_arr_expr, (en as simple_array_indexing).ind_expr, expr); + else + expr = find_operator(compiler_string_consts.assign_name, en, expr, loc); + last_call = expr; + } + else if (read_from_binary_file) + { + if (SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure == null) + AddError(new NotSupportedError(loc)); + if (!CanUseThisTypeForBinaryFiles(en.type)) + { + AddError(en.location, "CAN_NOT_READ_REFERENCE_DATA_FROM_BINARY_FILE"); + } + exl.AddElement(new typeof_operator(en.type, loc)); + function_node fn = convertion_data_and_alghoritms.select_function(exl,SystemLibrary.SystemLibInitializer.BinaryFileReadProcedure.SymbolInfo, loc); + expression_node expr = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray()); + expr = convertion_data_and_alghoritms.explicit_convert_type(expr, en.type); + expr = find_operator(compiler_string_consts.assign_name, en, expr, loc); + last_call = expr; + } + else + { + exl.AddElement(en); + try + { + function_node fn = null; + if (en.type.type_special_kind == SemanticTree.type_special_kind.short_string) + { + exl.AddElement(new int_const_node((en.type as short_string_type_node).Length,null)); + if (!read_from_file) + last_call = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.read_short_string_procedure.sym_info as function_node,get_location(ex),exl.ToArray()); + else + last_call = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.read_short_string_from_file_procedure.sym_info as function_node,get_location(ex),exl.ToArray()); + } + else if (en.type.type_special_kind == SemanticTree.type_special_kind.diap_type) + { + exl.remove(en); + en.type = en.type.base_type; + exl.AddElement(en); + fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc); + last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray()); + } + else + { + /// SSM 21/05/16 - read_from_text_file && - bug fix #161 + if (read_from_text_file && SystemLibrary.SystemLibInitializer.readln_procedure.Equal(sil) && parameters.expressions.Count == 2 && en.type == SystemLibrary.SystemLibrary.string_type) + { + fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.readln_procedure.SymbolInfo, loc); + readln_string_file = true; + } + else + fn = convertion_data_and_alghoritms.select_function(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc); + last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, get_location(ex), exl.ToArray()); + } + //last_call = convertion_data_and_alghoritms.create_full_function_call(exl, SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc, context.converted_type, context.top_function, true); + } + catch (NoFunctionWithSameArguments) + { + AddError(en.location, "CAN_NOT_READ"); + } + } + first_iteration = false; + } + } + if ((parameters == null) || (parameters.expressions.Count == 0)) // read(), readln() + { + if (SystemLibrary.SystemLibInitializer.read_procedure.Equal(sil)) + { + if (read_from_file) + exl.AddElement(file); + function_node fn = convertion_data_and_alghoritms.select_function(exl, + SystemLibrary.SystemLibInitializer.read_procedure.SymbolInfo, loc); + if (read_from_file) + last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, file); + else + last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc); + } + } + if (SystemLibrary.SystemLibInitializer.readln_procedure.Equal(sil)) // readln(...) + { + if (!readln_string_file) + { + if (last_call != null && convertion_data_and_alghoritms.statement_list_stack.size > 0) + convertion_data_and_alghoritms.statement_list_stack.top().statements.AddElement(last_call); + exl.clear(); + + if (read_from_file) + exl.AddElement(file); + + function_node fn = convertion_data_and_alghoritms.select_function(exl, + SystemLibrary.SystemLibInitializer.readln_procedure.SymbolInfo, loc); + if (read_from_file) + last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc, file); + else + last_call = convertion_data_and_alghoritms.create_simple_function_call(fn, loc); + } + } + return last_call; + } + + internal expression_node GetCurrentObjectReference(SymbolTable.Scope scope, definition_node dn, location loc) + { + if (context.WithSection) + if (scope != null) + if (context.WithVariables.ContainsKey(scope)) + return context.WithVariables[scope]; + else + if (context.WithTypes.Contains(scope)) + { + switch (dn.semantic_node_type) + { + case semantic_node_type.class_field : if (!(dn as class_field).IsStatic) AddError(new CanNotReferenceToNonStaticFieldWithType(dn as class_field,loc,null)); break; + case semantic_node_type.compiled_variable_definition : if (!(dn as compiled_variable_definition).IsStatic) AddError(new CanNotReferenceToNonStaticFieldWithType(dn as class_field,loc,null)); break; + case semantic_node_type.compiled_property_node: + case semantic_node_type.common_property_node : if ((dn as property_node).polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(new CanNotReferenceToNonStaticPropertyWithType(dn as property_node,loc,null)); break; + case semantic_node_type.compiled_function_node: + case semantic_node_type.common_method_node: if ((dn as function_node).polymorphic_state != SemanticTree.polymorphic_state.ps_static) AddError(new CanNotReferenceToNonStaticMethodWithType((dn as function_node).name,loc)); break; + } + } + if (context.inStaticArea()) + { + AddError(new CanNotReferenceToNonStaticFromStatic(dn,loc)); + return null; + } + else + return new this_node(context.converted_type, loc); + } + + + private expression_node create_with_expression(expression_node expr) + { + location sl = expr.location; + switch (expr.semantic_node_type) + { + case semantic_node_type.common_namespace_function_call: + case semantic_node_type.common_in_function_function_call: + case semantic_node_type.common_method_call: + case semantic_node_type.common_static_method_call: + case semantic_node_type.compiled_function_call: + case semantic_node_type.compiled_constructor_call: + case semantic_node_type.common_constructor_call: + case semantic_node_type.compiled_static_method_call: + return convertion_data_and_alghoritms.CreateVariableReference(context.add_var_definition(compiler_string_consts.GetTempVariableName(), sl, expr.type, expr), sl); + case semantic_node_type.class_field_reference: + (expr as class_field_reference).obj = create_with_expression((expr as class_field_reference).obj); + return expr; + case semantic_node_type.compiled_variable_reference: + (expr as compiled_variable_reference).obj = create_with_expression((expr as compiled_variable_reference).obj); + return expr; + case semantic_node_type.simple_array_indexing: + simple_array_indexing sar = expr as simple_array_indexing; + sar.simple_arr_expr = create_with_expression(sar.simple_arr_expr); + sar.ind_expr = create_with_expression(sar.ind_expr); + return sar; + case semantic_node_type.deref_node: + (expr as dereference_node).deref_expr = create_with_expression((expr as dereference_node).deref_expr); + return expr; + case semantic_node_type.basic_function_call: + return convertion_data_and_alghoritms.CreateVariableReference(context.add_var_definition(compiler_string_consts.GetTempVariableName(), sl, expr.type, expr), sl); + case semantic_node_type.as_node: + return convertion_data_and_alghoritms.CreateVariableReference(context.add_var_definition(compiler_string_consts.GetTempVariableName(), sl, expr.type, expr), sl); + } + return expr; + } + + public override void visit(SyntaxTree.with_statement _with_statement) + { + context.WithSection = true; + List Withs = new List(); + List VarRefs = new List(); + List WithTypesList = new List(); + statements_list stl = new statements_list(get_location(_with_statement.do_with), null, null); + SymbolTable.WithScope WithScope = new SymbolTable.WithScope(SymbolTable, context.CurrentScope, null); + convertion_data_and_alghoritms.statement_list_stack_push(stl, WithScope); + foreach (SyntaxTree.expression s_expr in _with_statement.do_with.expressions) + { + //expression_node expr = ret.visit(s_expr); + var mot = motivation_keeper.motivation; + motivation_keeper.set_motivation_to_expect_semantic_node(); + semantic_node sn = ret.visit(s_expr as SyntaxTree.syntax_tree_node); + motivation_keeper.reset(); + expression_node expr = sn as expression_node; + if (expr is null_const_node) + AddError(expr.location, "NIL_IN_THIS_CONTEXT_NOT_ALLOWED"); + if (expr is typed_expression) + expr = convert_typed_expression_to_function_call(expr as typed_expression); + if (expr != null) + { + if (expr.type is generic_instance_type_node) + AddError(get_location(s_expr), "UNEXPECTED_EXPRESSION_IN_WITH"); + variable_reference vr = expr as variable_reference; + if (expr.type == null) + AddError(get_location(s_expr), "UNEXPECTED_EXPRESSION_IN_WITH"); + if (expr.type is ref_type_node) + AddError(get_location(s_expr), "UNEXPECTED_EXPRESSION_IN_WITH"); + if (vr == null) + { + location sl = get_location(s_expr); + if (expr.type.type_special_kind != SemanticTree.type_special_kind.record) + vr = convertion_data_and_alghoritms.CreateVariableReference(context.add_var_definition(compiler_string_consts.GetTempVariableName(), sl, expr.type, expr), sl); + else + expr = create_with_expression(expr); + } + if (vr != null && vr is class_field_reference && vr.type.type_special_kind == SemanticTree.type_special_kind.record) + { + vr = null; + expr = create_with_expression(expr); + } + if (vr != null) + { + VarRefs.Add(vr); + if (vr.type.Scope == null) + { + if (vr.type is compiled_type_node) + (vr.type as compiled_type_node).scope = new NetHelper.NetTypeScope((vr.type as compiled_type_node).compiled_type, SystemLibrary.SystemLibrary.symtab); + else + throw new CompilerInternalError("Cannot create With statement because variable reference scope == null"); + } + //если не нужны локальные перекрытия, здесь нужна проверка + Withs.Add(vr.type.Scope); + } + else + { + VarRefs.Add(expr); + Withs.Add(expr.type.Scope); + } + } + else if (sn is type_node) + { + type_node tn = sn as type_node; + if (tn.IsInterface) + AddError(get_location(s_expr), "UNEXPECTED_EXPRESSION_IN_WITH"); + Withs.Add(tn.Scope); + while (tn != null) + { + if (tn.Scope == null && tn is compiled_type_node) + { + (tn as compiled_type_node).init_scope(); + } + WithTypesList.Add(tn.Scope); + tn = tn.base_type; + } + } + else if (sn is compiled_namespace_node) + { + compiled_namespace_node nn = sn as compiled_namespace_node; + Withs.Add(nn.scope); + } + } + WithScope.WithScopes = Withs.ToArray(); + + Dictionary OldWithVariables = new Dictionary(); + foreach (expression_node vr in VarRefs) + { + if (context.WithVariables.ContainsKey(vr.type.Scope)) + { + //перекрытие области + if (OldWithVariables.ContainsKey(vr.type.Scope)) + //Это локальные перекрытия + OldWithVariables[vr.type.Scope] = context.WithVariables[vr.type.Scope]; + else + OldWithVariables.Add(vr.type.Scope, context.WithVariables[vr.type.Scope]); + context.WithVariables[vr.type.Scope] = vr; + } + else + { + //добавляем текущие with + context.WithVariables.Add(vr.type.Scope, vr); + + } + //ivan dobavil dlja bazovyh klassov + type_node tn = vr.type.base_type; + while (tn != null) + { + if (tn.Scope == null && tn is compiled_type_node) + { + (tn as compiled_type_node).init_scope(); + } + if (tn.Scope != null) + if (!context.WithVariables.ContainsKey(tn.Scope)) + context.WithVariables.Add(tn.Scope, vr); + else + { + if (OldWithVariables.ContainsKey(tn.Scope)) + //Это локальные перекрытия + OldWithVariables[tn.Scope] = context.WithVariables[tn.Scope]; + else + OldWithVariables.Add(tn.Scope, context.WithVariables[tn.Scope]); + context.WithVariables[tn.Scope] = vr; + } + tn = tn.base_type; + } + } + + //Ivan dobavil dlja tipov + + foreach (SymbolTable.Scope sc in WithTypesList) + { + if (!context.WithTypes.Contains(sc)) + context.WithTypes.Push(sc); + } + + stl.statements.AddElement(ret.visit(_with_statement.what_do)); + + //восстанавливаем перекрытия + foreach (SymbolTable.Scope sc in OldWithVariables.Keys) + context.WithVariables[sc] = OldWithVariables[sc]; + //удаляем текущие with + foreach (expression_node vr in VarRefs) + { + context.WithVariables.Remove(vr.type.Scope); + type_node tn = vr.type.base_type; + while (tn != null) + { + if (tn.Scope != null && context.WithVariables.ContainsKey(tn.Scope)) + context.WithVariables.Remove(tn.Scope); + tn = tn.base_type; + } + } + foreach (SymbolTable.Scope sc in WithTypesList) + { + context.WithTypes.Pop(); + } + + context.WithSection = context.WithVariables.Count > 0; + + convertion_data_and_alghoritms.statement_list_stack_pop(); + return_value(stl); + } + + public override void visit(SyntaxTree.labeled_statement _labeled_statement) + { + convertion_data_and_alghoritms.check_node_parser_error(_labeled_statement.label_name); + if (_labeled_statement.to_statement is var_statement || _labeled_statement.to_statement is SyntaxTree.assign_var_tuple) + { + var stmt = new SyntaxTree.labeled_statement(_labeled_statement.label_name,new SyntaxTree.empty_statement()); + ReplaceStatementUsingParent(_labeled_statement, new List + {stmt, _labeled_statement.to_statement + }); + ProcessNode(stmt); + return; + } + List sil = context.CurrentScope.FindOnlyInScopeAndBlocks(_labeled_statement.label_name.name); + /*if (_labeled_statement.to_statement is SyntaxTree.var_statement || _labeled_statement.to_statement is SyntaxTree.assign_var_tuple) + { + AddError(get_location(_labeled_statement.label_name), "LABELED_DECLARATION_NOT_ALLOWED"); + }*/ + if (sil == null) + { + AddError(new UndefinedNameReference(_labeled_statement.label_name.name, get_location(_labeled_statement.label_name))); + } + label_node lab = sil.FirstOrDefault().sym_info as label_node; + if (lab == null) + { + AddError(get_location(_labeled_statement.label_name), "IDENT_{0}_IS_NOT_LABEL", _labeled_statement.label_name.name); + } + // SSM - Patch повторного определения меток в подпрограммах при наличии лямбд + if (lambdaProcessingState != LambdaProcessingState.FinishPhase) + if (lab.is_defined) + { + AddError(get_location(_labeled_statement.label_name), "LABEL_{0}_REDEFINED", _labeled_statement.label_name.name); + } + lab.is_defined = true; + lab.comprehensive_code_block = context.block_stack.Peek(); + foreach (goto_statement gs in lab.goto_statements) + { + if (!context.check_can_goto(lab.comprehensive_code_block, gs.comprehensive_code_block) && gs.location != null) + { + AddError(gs.location, "BLOCKED_LABEL_{0}_GOTO", lab.name); + } + } + convertion_data_and_alghoritms.check_node_parser_error(_labeled_statement.to_statement); + statement_node snode = ret.visit((SyntaxTree.statement)_labeled_statement.to_statement); + labeled_statement las = new labeled_statement(lab, snode, get_location(_labeled_statement)); + ret.return_value((statement_node)las); + } + + public override void visit(SyntaxTree.goto_statement _goto_statement) + { + List sil = context.CurrentScope.FindOnlyInScopeAndBlocks(_goto_statement.label.name); + if (sil == null) + { + AddError(new UndefinedNameReference(_goto_statement.label.name, get_location(_goto_statement.label))); + } + label_node lab = sil.FirstOrDefault().sym_info as label_node; + if (lab == null) + { + AddError(get_location(_goto_statement.label), "IDENT_{0}_IS_NOT_LABEL", _goto_statement.label.name); + } + //if (lab.goto_blocked) + //{ + // throw new BlockedLabelGoto(_goto_statement.label.name, get_location(_goto_statement.label)); + //} + goto_statement gs = new goto_statement(lab, get_location(_goto_statement)); + gs.comprehensive_code_block = context.block_stack.Peek(); + lab.goto_statements.Add(gs); + if (lab.comprehensive_code_block != null) + { + // последнее условие - для goto, которые генерируются в автомате yield, не рассматривать эту ошибку + if (!context.check_can_goto(lab.comprehensive_code_block, gs.comprehensive_code_block) && _goto_statement.source_context != null) + { + AddError(gs.location, "BLOCKED_LABEL_{0}_GOTO", lab.name); + } + } + ret.return_value((statement_node)gs); + } + + public override void visit(SyntaxTree.empty_statement _empty_statement) + { + return_value(new empty_statement(get_location(_empty_statement))); + } + + private addressed_expression create_class_static_field_reference(type_node tn, definition_node dn, + SyntaxTree.ident id_right) + { + switch (dn.semantic_node_type) + { + case semantic_node_type.class_field: + { + class_field cf = (class_field)dn; + if (cf.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + { + AddError(new CanNotReferenceToNonStaticFieldWithType(cf, get_location(id_right), tn)); + } + static_class_field_reference scfr = new static_class_field_reference(cf, get_location(id_right)); + return scfr; + } + case semantic_node_type.compiled_variable_definition: + { + compiled_variable_definition cvd = (compiled_variable_definition)dn; + if (cvd.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + { + AddError(new CanNotReferenceToNonStaticFieldWithType(cvd, get_location(id_right), tn)); + } + static_compiled_variable_reference scvr = new static_compiled_variable_reference(cvd, get_location(id_right)); + return scvr; + } + } + throw new CompilerInternalError("Error in create static class field reference."); + } + + private addressed_expression create_addressed_with_type_expression(type_node tn, SyntaxTree.ident id_right, + SymbolInfo si_right) + { + definition_node dn = null; + if (!internal_is_assign) + dn = context.check_name_node_type(id_right.name, si_right, get_location(id_right), + general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node); + else + dn = context.check_name_node_type(id_right.name, si_right, get_location(id_right), + general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node,general_node_type.constant_definition); + if (dn.general_node_type == general_node_type.constant_definition) + AddError(get_location(id_right), "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT"); + switch (dn.general_node_type) + { + case general_node_type.variable_node: + { + return create_class_static_field_reference(tn, dn, id_right); + } + case general_node_type.property_node: + { + property_node pn = (property_node)dn; + if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + { + AddError(new CanNotReferenceToNonStaticPropertyWithType(pn, get_location(id_right), tn)); + } + static_property_reference pr = new static_property_reference(pn, get_location(id_right)); + return pr; + } + case general_node_type.event_node: + { + if (dn.semantic_node_type == semantic_node_type.compiled_event) + { + compiled_event ce = (compiled_event)dn; + if (!ce.is_static) + { + //throw new NonStaticAndStaticEvevnt(); + } + static_event_reference ser = new static_event_reference(ce, get_location(id_right)); + return ser; + } + else if (dn.semantic_node_type == semantic_node_type.common_event) + { + common_event ce = (common_event)dn; + if (!ce.is_static) + { + //throw new NonStaticAndStaticEvevnt(); + } + static_event_reference ser = new static_event_reference(ce, get_location(id_right)); + return ser; + } + else if (dn.semantic_node_type == semantic_node_type.common_namespace_event) + { + common_namespace_event cne = dn as common_namespace_event; + static_event_reference ser = new static_event_reference(cne, get_location(id_right)); + return ser; + } + break; + } + default : return null; + } + throw new CompilerInternalError("Invalid right type expression"); + } + + private expressions_list convert_expression_list(List expr_list) + { + expressions_list exprs = new expressions_list(); + foreach (SyntaxTree.expression en in expr_list) + exprs.AddElement(convert_strong(en)); + return exprs; + } + + + private base_function_call create_static_method_call_with_params(function_node fn, location loc, type_node tn, bool procedure_allowed, expressions_list parametrs) + { + base_function_call bfc = create_static_method_call(fn, loc, tn, procedure_allowed); + bfc.parameters.AddRange(parametrs); + return bfc; + } + private base_function_call create_static_method_call(function_node fn, location loc, type_node tn, bool procedure_allowed) + { + if ((!procedure_allowed) && (fn.return_value_type == null)) + { + AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn.name); + } + if (fn.semantic_node_type == semantic_node_type.common_method_node) + { + common_method_node cmn = (common_method_node)fn; + if (cmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + { + //ssyy изменил + if (!cmn.is_constructor) + { + AddError(new CanNotCallNonStaticMethodWithClass(tn, loc, fn)); + } + if (cmn.cont_type.IsStatic) + AddError(new SimpleSemanticError(loc, "STATIC_CONSTRUCTOR_CALL")); + if (cmn.cont_type.IsAbstract) + AddError(new SimpleSemanticError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", cmn.cont_type.name)); + common_constructor_call csmc2 = new common_constructor_call(cmn, loc); + return csmc2; + //if (cmn.pascal_associated_constructor==null) + //{ + // throw new CanNotCallNonStaticMethodWithClass(tn,loc,fn); + //} + //common_constructor_call csmc2=new common_constructor_call(cmn.pascal_associated_constructor,loc); + //return csmc2; + //\ssyy + } + common_static_method_call csmc = new common_static_method_call(cmn, loc); + return csmc; + } + if (fn.semantic_node_type == semantic_node_type.compiled_function_node) + { + compiled_function_node cfn = (compiled_function_node)fn; + if (cfn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + { + AddError(new CanNotCallNonStaticMethodWithClass(tn, loc, fn)); + } + compiled_static_method_call csmc2 = new compiled_static_method_call(cfn, loc); + return csmc2; + } + if (fn.semantic_node_type == semantic_node_type.compiled_constructor_node) + { + compiled_constructor_node ccn = (compiled_constructor_node)fn; + compiled_constructor_call ccc = new compiled_constructor_call(ccn, loc); + return ccc; + } + if (fn.semantic_node_type == semantic_node_type.basic_function_node) + { + return new basic_function_call(fn as basic_function_node, loc); + } + if (fn.semantic_node_type == semantic_node_type.common_namespace_function_node && (fn as common_namespace_function_node).ConnectedToType != null) + { + return new common_namespace_function_call(fn as common_namespace_function_node,loc); + } + if (fn.semantic_node_type == semantic_node_type.indefinite_definition_node) + { + return new indefinite_function_call(fn, loc); + } + throw new CompilerInternalError("Invalid method kind"); + } + + private expression_node create_static_expression(type_node tn, SyntaxTree.ident id_right, + List si_right) + { + definition_node dn = null; + if (si_right?.FirstOrDefault().sym_info is common_event && (si_right?.FirstOrDefault().sym_info as common_event).cont_type == tn) + dn = context.check_name_node_type(id_right.name, si_right?.FirstOrDefault(), get_location(id_right), general_node_type.variable_node, + general_node_type.function_node, general_node_type.property_node, general_node_type.constant_definition, general_node_type.event_node); + else + dn = context.check_name_node_type(id_right.name, si_right?.FirstOrDefault(), get_location(id_right), general_node_type.variable_node, + general_node_type.function_node, general_node_type.property_node, general_node_type.constant_definition); + switch (dn.general_node_type) + { + case general_node_type.variable_node: + { + return create_class_static_field_reference(tn, dn, id_right); + } + case general_node_type.constant_definition: + { + constant_definition_node cdn = (constant_definition_node)dn; + return cdn.const_value.get_constant_copy(get_location(id_right)); + } + case general_node_type.function_node: + { + if (dn is compiled_function_node) + { + if ((dn as compiled_function_node).ConnectedToType == tn) + { + if (si_right.Count() > 1) + { + List temp = new List(); + temp = si_right.GetRange(1, si_right.Count() - 1); + return create_static_expression(tn, id_right, temp); + } + else + AddError(new UndefinedNameReference(id_right.name, get_location(id_right))); + } + } + else if (dn is common_namespace_function_node) + { + if ((dn as common_namespace_function_node).ConnectedToType == tn) + { + if (si_right.Count() > 1) + { + List temp = new List(); + temp = si_right.GetRange(1, si_right.Count() - 1); + return create_static_expression(tn, id_right, temp); + } + else + AddError(new UndefinedNameReference(id_right.name, get_location(id_right))); + } + } + if (dn.semantic_node_type == semantic_node_type.indefinite_definition_node) + { + return new indefinite_reference(dn as indefinite_definition_node, get_location(id_right)); + } + + return make_delegate_wrapper(null, si_right, get_location(id_right), true); + + } + case general_node_type.property_node: + { + property_node pn = (property_node)dn; + if (pn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + { + AddError(new CanNotReferenceToNonStaticPropertyWithType(pn, get_location(id_right), tn)); + } + function_node fn = pn.get_function; + if (fn == null) + { + AddError(new ThisPropertyCanNotBeReaded(pn, get_location(id_right))); + } + location lloc = get_location(id_right); + check_property_no_params(pn, lloc); + return create_static_method_call(fn, lloc, tn, false); + } + case general_node_type.event_node: + { + + static_event_reference ser = new static_event_reference((event_node)dn, get_location(id_right)); + return ser; + } + } + throw new CompilerInternalError("Error in creating static expression."); + } + + private void dot_node_as_type_ident(type_node tn, SyntaxTree.ident id_right, motivation mot) + { + List si_right = tn.find_in_type(id_right.name, context.CurrentScope); + if (si_right == null) + { + AddError(new MemberIsNotDeclaredInType(id_right, get_location(id_right), tn)); + } + switch (mot) + { + case motivation.address_receiving: + { + return_addressed_value(create_addressed_with_type_expression(tn, id_right, si_right?.FirstOrDefault())); + return; + } + case motivation.expression_evaluation: + { + return_value(create_static_expression(tn, id_right, si_right)); + return; + } + case motivation.semantic_node_reciving: + { + if (si_right.FirstOrDefault().sym_info.general_node_type == general_node_type.type_node) + return_semantic_value(si_right.FirstOrDefault().sym_info as type_node); + else + return_semantic_value(create_static_expression(tn, id_right, si_right)); + return; + } + } + throw new CompilerInternalError("Invalid motivation"); + } + + private void dot_node_as_namespace_ident(namespace_node nn, SyntaxTree.ident id_right, motivation mot) + { + List si_right = nn.findOnlyInNamespace(id_right.name); + if (si_right == null) + { + AddError(new MemberIsNotDeclaredInNamespace(id_right, get_location(id_right), nn)); + } + if (si_right.Count > 0 && si_right[0].sym_info == nn) + AddError(new MemberIsNotDeclaredInNamespace(id_right, get_location(id_right), nn)); + switch (mot) + { + case motivation.address_receiving: + { + return_addressed_value(ident_address_reciving(si_right?.FirstOrDefault(), id_right)); + return; + } + case motivation.expression_evaluation: + { + return_value(ident_value_reciving(si_right, id_right)); + return; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(ident_semantic_reciving(si_right, id_right)); + return; + } + } + throw new CompilerInternalError("Unsupported motivation"); + } + + private void dot_node_as_unit_ident(common_unit_node cun, SyntaxTree.ident id_right, motivation mot) + { + dot_node_as_namespace_ident(cun.namespaces[0], id_right, mot); + } + + private void dot_node_as_ident_dot_template_ident(SyntaxTree.ident id_left, SyntaxTree.ident_with_templateparams template_id_right, + motivation mot) + { + List si_left = context.find(id_left.name); + SyntaxTree.ident id_right = template_id_right.name as SyntaxTree.ident; + if (si_left == null) + { + AddError(new UndefinedNameReference(id_left.name, get_location(id_left))); + } + definition_node dn = context.check_name_node_type(id_left.name, si_left?.FirstOrDefault(), get_location(id_left), + general_node_type.constant_definition, general_node_type.function_node, + general_node_type.namespace_node, general_node_type.property_node, + general_node_type.type_node, general_node_type.variable_node, + general_node_type.unit_node); + switch (dn.general_node_type) + { + case general_node_type.constant_definition: + case general_node_type.function_node: + case general_node_type.property_node: + case general_node_type.variable_node: + { + expression_node ex_nd = ident_value_reciving(si_left, id_left); + dot_node_as_expression_dot_template_ident(ex_nd, template_id_right, mot, id_left); + return; + } + case general_node_type.namespace_node: + { + //throw new CompilerInternalError("Unsupported now."); + namespace_node nn = dn as namespace_node; + dot_node_as_namespace_ident(nn, id_right, mot); + return; + } + case general_node_type.type_node: + { + type_node tn = dn as type_node; + dot_node_as_type_ident(tn, id_right, mot); + return; + } + case general_node_type.unit_node: + { + //throw new NotSupportedError(get_location(id_left)); + dot_node_as_unit_ident((common_unit_node)dn, id_right, mot); + return; + } + } + return; + } + + private void dot_node_as_ident_dot_ident(SyntaxTree.ident id_left, SyntaxTree.ident id_right, + motivation mot) + { + List si_left = context.find(id_left.name); + if (si_left == null) + { + AddError(new UndefinedNameReference(id_left.name, get_location(id_left))); + } + definition_node dn = context.check_name_node_type(id_left.name, si_left?.FirstOrDefault(), get_location(id_left), + general_node_type.constant_definition, general_node_type.function_node, + general_node_type.namespace_node, general_node_type.property_node, + general_node_type.type_node, general_node_type.variable_node, + general_node_type.unit_node); + switch (dn.general_node_type) + { + case general_node_type.constant_definition: + case general_node_type.function_node: + case general_node_type.property_node: + case general_node_type.variable_node: + { + expression_node ex_nd = null; + if (id_left is inherited_ident) + ex_nd = inherited_ident_value_reciving(id_left as inherited_ident); + else + ex_nd = ident_value_reciving(si_left, id_left); + dot_node_as_expression_dot_ident(ex_nd, id_right, mot, id_left); + return; + } + case general_node_type.namespace_node: + { + //throw new CompilerInternalError("Unsupported now."); + namespace_node nn = dn as namespace_node; + dot_node_as_namespace_ident(nn, id_right, mot); + return; + } + case general_node_type.type_node: + { + type_node tn = dn as type_node; + dot_node_as_type_ident(tn, id_right, mot); + return; + } + case general_node_type.unit_node: + { + //throw new NotSupportedError(get_location(id_left)); + dot_node_as_unit_ident((common_unit_node)dn, id_right, mot); + return; + } + } + return; + } + + private expression_node convert_if_typed_expression_to_function_call(expression_node expr) + { + if (expr is typed_expression) + return convert_typed_expression_to_function_call(expr as typed_expression); + return expr; + } + + internal expression_node convert_typed_expression_to_function_call(typed_expression te) + { + delegated_methods dm = te.type as delegated_methods; + if (dm == null) + { + return te; + } + base_function_call bfc = dm.empty_param_method; + if (bfc == null) + { + return te; + } + if (bfc.type == null) + return te; + function_node fn = bfc.simple_function_node; + common_namespace_function_node cnfn = fn as common_namespace_function_node; + if ((fn.parameters.Count == 1 || cnfn != null && fn.parameters.Count == 2 && cnfn.ConnectedToType != null) + && (fn.parameters[fn.parameters.Count - 1].is_params || fn.parameters[fn.parameters.Count - 1].default_value != null) + || fn.parameters.Count > 0 && fn.num_of_default_parameters == fn.parameters.Count) + { + fn = convertion_data_and_alghoritms.select_function(bfc.parameters, new List { new SymbolInfo(fn) }, bfc.location); + if (fn.polymorphic_state == SemanticTree.polymorphic_state.ps_static || fn is common_namespace_function_node || fn is basic_function_node) + bfc = convertion_data_and_alghoritms.create_simple_function_call(fn, bfc.location, bfc.parameters.ToArray()) as base_function_call; + else + { + expression_node obj = null; + if (bfc is common_method_call) + obj = (bfc as common_method_call).obj; + else if (bfc is compiled_function_call) + obj = (bfc as compiled_function_call).obj; + bfc = convertion_data_and_alghoritms.create_method_call(fn, bfc.location, obj, bfc.parameters.ToArray()) as base_function_call; + + } + } + else + { + function_node[] empty_param_methods = dm.empty_param_methods; + + List root_sil = new List { new SymbolInfo(empty_param_methods[0]) }; + for (int i = 1; i < empty_param_methods.Length; i++) + { + root_sil.Add(new SymbolInfo(empty_param_methods[i])); + } + compiled_function_node cfn = fn as compiled_function_node; + if ((fn.parameters.Count == 1 || cfn != null && fn.parameters.Count == 2 && cfn.ConnectedToType != null) + && (fn.parameters[fn.parameters.Count - 1].is_params || fn.parameters[fn.parameters.Count - 1].default_value != null)) + { + fn = convertion_data_and_alghoritms.select_function(bfc.parameters, root_sil, bfc.location); + bfc = create_static_method_call_with_params(fn, bfc.location, fn.return_value_type, true, bfc.parameters); + } + else if (fn.parameters.Count == 1 && cfn != null && cfn.ConnectedToType != null) + { + fn = convertion_data_and_alghoritms.select_function(bfc.parameters, root_sil, bfc.location); + bfc = create_static_method_call_with_params(fn, bfc.location, fn.return_value_type, true, bfc.parameters); + } + } + if (bfc is common_method_call) + { + common_method_node cmn = (bfc as common_method_call).function_node; + if (cmn != null && cmn.is_generic_function && !cmn.is_generic_function_instance && cmn.parameters.Count == 0) + { + cmn = (common_method_node)generic_convertions.DeduceFunction(cmn, new expressions_list(), true, context, bfc.location); + bfc = new common_method_call(cmn, (bfc as common_method_call).obj, bfc.location); + } + } + return bfc; + } + + public void try_convert_typed_expression_to_function_call(ref expression_node en) + { + if (en.semantic_node_type == semantic_node_type.typed_expression) + { + en = convert_typed_expression_to_function_call((typed_expression)en); + } + } + + private addressed_expression create_class_field_reference(expression_node en, definition_node dn, SyntaxTree.ident id_right) + { + try_convert_typed_expression_to_function_call(ref en); + if (dn.semantic_node_type == semantic_node_type.class_field) + { + class_field cf = (class_field)dn; + if (cf.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + AddError(new CanNotReferanceToStaticFieldWithExpression(cf, get_location(id_right), en)); + } + class_field_reference cfr = new class_field_reference(cf, en, get_location(id_right)); + //return_value(cfr); + return cfr; + } + if (dn.semantic_node_type == semantic_node_type.compiled_variable_definition) + { + compiled_variable_definition cfd = (compiled_variable_definition)dn; + if (cfd.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + AddError(new CanNotReferanceToStaticFieldWithExpression(cfd, get_location(id_right), en)); + } + compiled_variable_reference cfr2 = new compiled_variable_reference(cfd, en, get_location(id_right)); + //return_value(cfr2); + return cfr2; + } +#if (DEBUG) + throw new CompilerInternalError("Invalid variable kind"); +#endif + return null; + } + + private base_function_call create_not_static_method_call(function_node fn, expression_node en, location loc, bool procedure_allowed) + { + try_convert_typed_expression_to_function_call(ref en); + if ((!procedure_allowed) && (fn.return_value_type == null)) + { + AddError(loc, "FUNCTION_EXPECTED_PROCEDURE_{0}_MEET", fn.name); + } + if (fn.semantic_node_type == semantic_node_type.common_method_node) + { + common_method_node cmn = (common_method_node)fn; + if (cmn.is_constructor) + { + AddError(loc, "CAN_NOT_CALL_CONSTRUCTOR_AS_PROCEDURE"); + } + if (cmn.original_function != null && cmn.original_function is compiled_function_node && (cmn.original_function as compiled_function_node).ConnectedToType != null) + { + common_static_method_call csmc = new common_static_method_call(cmn, loc); + return csmc; + } + if (cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + AddError(new CanNotCallStaticMethodWithExpression(en, fn)); + } + + common_method_call cmc = new common_method_call(cmn, en, loc); + cmc.virtual_call = !inherited_ident_processing; + return cmc; + } + if (fn.semantic_node_type == semantic_node_type.compiled_function_node) + { + compiled_function_node cfn = (compiled_function_node)fn; + if (cfn.ConnectedToType != null) + { + compiled_static_method_call csmc = new compiled_static_method_call(cfn, loc); + return csmc; + } + else + { + if (cfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + if (!cfn.is_extension_method) + AddError(new CanNotCallStaticMethodWithExpression(en, fn)); + else + return new compiled_static_method_call(cfn, loc); + } + compiled_function_call cfc = new compiled_function_call(cfn, en, loc); + cfc.virtual_call = !inherited_ident_processing; + return cfc; + } + } + if (fn.semantic_node_type == semantic_node_type.compiled_constructor_node) + { + AddError(loc, "CAN_NOT_CALL_CONSTRUCTOR_AS_PROCEDURE"); + } + if (fn.semantic_node_type == semantic_node_type.common_namespace_function_node && (fn as common_namespace_function_node).ConnectedToType != null) + { + common_namespace_function_call cnfc = new common_namespace_function_call(fn as common_namespace_function_node,loc); + //cnfc.parameters.AddElement(en); + return cnfc; + } + if (fn.semantic_node_type == semantic_node_type.indefinite_definition_node) + { + indefinite_function_call ifc = new indefinite_function_call(fn, loc); + return ifc; + } + throw new CompilerInternalError("Invalid method kind"); + } + + private expression_node expression_value_reciving(SyntaxTree.ident id_right, List sil, expression_node en, bool expected_delegate) + { + general_node_type[] node_types; + if (en is this_node || LambdaHelper.IsCapturedSelf(en)) + node_types = new general_node_type[] { general_node_type.variable_node, + general_node_type.function_node, general_node_type.property_node, general_node_type.constant_definition, general_node_type.event_node}; + else + node_types = new general_node_type[] { general_node_type.variable_node, + general_node_type.function_node, general_node_type.property_node, general_node_type.constant_definition}; + definition_node dn = context.check_name_node_type(id_right.name, sil?.FirstOrDefault(), get_location(id_right), node_types); + switch (dn.general_node_type) + { + /*case general_node_type.constant_defenition: + { + constant_definition_node cdn=(constant_definition_node)dn; + return cdn.const_value; + }*/ + case general_node_type.variable_node: + { + return create_class_field_reference(en, dn, id_right); + } + case general_node_type.function_node: + { + if (dn.semantic_node_type == semantic_node_type.indefinite_definition_node) + { + return new indefinite_reference(dn as indefinite_definition_node, get_location(id_right)); + } + if (expected_delegate && en != null) + { + function_node tmp_fn = null; + bool has_empty_methods = false; + bool only_extension_methods = true; + if (sil != null) + { + foreach (SymbolInfo tmp_si in sil) + { + tmp_fn = tmp_si.sym_info as function_node; + if (tmp_fn != null) + { + if (!tmp_fn.is_extension_method) + only_extension_methods = false; + else + { + if (tmp_fn.parameters.Count == 1 || tmp_fn.parameters.Count == 2 && (tmp_fn.parameters[1].is_params || tmp_fn.parameters[1].default_value != null)) + has_empty_methods = true; + } + } + } + } + if (has_empty_methods && only_extension_methods) + expected_delegate = false; + } + if (expected_delegate) + { + return make_delegate_wrapper(en, sil, get_location(id_right), false); + } + else + { + function_node tmp_fn = null; + expressions_list pars = new expressions_list(); + if (en != null) + if(sil != null) + foreach(SymbolInfo tmp_si in sil) + { + tmp_fn = tmp_si.sym_info as function_node; + if (tmp_fn != null && tmp_fn.is_extension_method && + (tmp_fn.parameters.Count == 1 || tmp_fn.parameters.Count == 2 && (tmp_fn.parameters[1].is_params || tmp_fn.parameters[1].default_value != null))) + { + pars.AddElement(en); + break; + } + } + function_node fn = convertion_data_and_alghoritms.select_function(pars, sil, get_location(id_right)); + if (!fn.is_extension_method && fn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + return create_not_static_method_call(fn, en, get_location(id_right), false); + else + return create_static_method_call_with_params(fn, get_location(id_right), fn.return_value_type, false, pars); + } + } + case general_node_type.property_node: + { + property_node pn = (property_node)dn; + if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + AddError(new CanNotReferenceToStaticPropertyWithExpression(pn, get_location(id_right), pn.comprehensive_type)); + } + function_node fn = pn.get_function; + if (fn == null) + { + AddError(new ThisPropertyCanNotBeReaded(pn, get_location(id_right))); + } + location lloc = get_location(id_right); + check_property_no_params(pn, lloc); + return create_not_static_method_call(fn, en, lloc, false); + } + case general_node_type.constant_definition: + { + //throw new ConstMemberCannotBeAccessedWithAnInstanceReference((class_constant_definition)dn, get_location(id_right)); + return ((constant_definition_node)dn).const_value.get_constant_copy(get_location(id_right)); + } + case general_node_type.event_node: + { + if (dn.semantic_node_type == semantic_node_type.compiled_event) + { + compiled_event ce = (compiled_event)dn; + if (ce.is_static) + { + //throw new NonStaticAndStaticEvevnt(); + } + nonstatic_event_reference ser = new nonstatic_event_reference(en, ce, get_location(id_right)); + return ser; + } + else if (dn.semantic_node_type == semantic_node_type.common_event) + { + common_event ce = (common_event)dn; + if (ce.is_static) + { + //throw new NonStaticAndStaticEvevnt(); + } + nonstatic_event_reference ser = new nonstatic_event_reference(en, ce, get_location(id_right)); + return ser; + } + break; + } + } + throw new CompilerInternalError("Invalid class member"); + } + + private addressed_expression address_expression_reciving(SyntaxTree.ident id_right, SymbolInfo si, + expression_node en) + { + if (si != null && si.sym_info != null && + si.sym_info.semantic_node_type == semantic_node_type.indefinite_definition_node) + { + return new indefinite_reference(si.sym_info as indefinite_definition_node, get_location(id_right)); + } + definition_node dn = null; + if (!internal_is_assign) + dn = context.check_name_node_type(id_right.name, si, get_location(id_right), + general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node); + else + dn = context.check_name_node_type(id_right.name, si, get_location(id_right), + general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node, general_node_type.constant_definition); + if (dn.general_node_type == general_node_type.constant_definition) + { + AddError(get_location(id_right), "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT"); + } + switch (dn.general_node_type) + { + case general_node_type.variable_node: + { + return create_class_field_reference(en, dn, id_right); + } + case general_node_type.property_node: + { + property_node pn = (property_node)dn; + if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + AddError(new CanNotReferenceToStaticPropertyWithExpression(pn, get_location(id_right), pn.comprehensive_type)); + } + try_convert_typed_expression_to_function_call(ref en); + non_static_property_reference pr = new non_static_property_reference(pn, en, get_location(id_right)); + return pr; + } + case general_node_type.event_node: + { + if (dn.semantic_node_type == semantic_node_type.compiled_event) + { + compiled_event ce = (compiled_event)dn; + if (ce.is_static) + { + //throw new NonStaticAndStaticEvevnt(); + } + nonstatic_event_reference ser = new nonstatic_event_reference(en, ce, get_location(id_right)); + return ser; + } + else if (dn.semantic_node_type == semantic_node_type.common_event) + { + common_event ce = (common_event)dn; + if (ce.is_static) + { + //throw new NonStaticAndStaticEvevnt(); + } + nonstatic_event_reference ser = new nonstatic_event_reference(en, ce, get_location(id_right)); + return ser; + } + break; + } + default : return null; + } + throw new CompilerInternalError("Undefined expression to address reciving"); + } + + private bool has_property(ref List sil) + { + int si_index = 0; + if (sil != null) + { + while (si_index < sil.Count()) + { + if (sil[si_index].sym_info is compiled_property_node || sil[si_index].sym_info is common_property_node) + { + sil.RemoveRange(0, si_index); + return true; + } + ++si_index; + } + } + return false; + } + + private void dot_node_as_expression_dot_template_ident(expression_node en, SyntaxTree.ident_with_templateparams template_id_right, motivation mot, addressed_value syntax_node) + { + SyntaxTree.ident id_right = template_id_right.name as ident; + if (en is typed_expression) + try_convert_typed_expression_to_function_call(ref en); + List sil = en.type.find_in_type(id_right.name, context.CurrentScope); + if (sil == null) + { + AddError(new MemberIsNotDeclaredInType(id_right, get_location(id_right), en.type)); + } + + try_convert_typed_expression_to_function_call(ref en); + + switch (mot) + { + case motivation.address_receiving: + { + return_addressed_value(address_expression_reciving(id_right, sil?.FirstOrDefault(), en)); + return; + } + case motivation.expression_evaluation: + { + if (can_convert_to_method_call(ref sil)) + { + //dot_node dnode = new dot_node(syntax_node, template_id_right); + template_id_right.name = new dot_node(syntax_node, id_right); + method_call mc = new method_call(template_id_right, new expression_list()); + mc.visit(this); + return; + } + return_value(expression_value_reciving(id_right, sil, en, true)); + return; + } + case motivation.semantic_node_reciving: + { + if (sil.FirstOrDefault().sym_info is function_node && (sil.FirstOrDefault().sym_info as function_node).is_extension_method) + has_property(ref sil); + return_semantic_value(expression_value_reciving(id_right, sil, en, true)); + return; + } + } + throw new CompilerInternalError("Invalid motivation."); + } + + private void dot_node_as_expression_dot_ident(expression_node en, SyntaxTree.ident id_right, motivation mot, addressed_value syntax_node) + { + if (en is typed_expression) + try_convert_typed_expression_to_function_call(ref en); + if (en is typed_expression) + { + AddError(new MemberIsNotDeclaredInType(id_right, get_location(id_right), en.type)); + } + List sil = en.type.find_in_type(id_right.name, context.CurrentScope); + if (en.type.IsEnum && sil != null && sil[0].sym_info is class_constant_definition) // l.A + { + AddError(get_location(id_right), "ACCESS_TO_ENUM_CONST_THROUGH_OBJECT"); + } + if (sil == null) + { + AddError(new MemberIsNotDeclaredInType(id_right, get_location(id_right), en.type)); + } + + try_convert_typed_expression_to_function_call(ref en); + switch (mot) + { + case motivation.address_receiving: + { + return_addressed_value(address_expression_reciving(id_right, sil?.FirstOrDefault(), en)); + return; + } + case motivation.expression_evaluation: + { + if (can_convert_to_method_call(ref sil)) + { + dot_node dnode = new dot_node(syntax_node, id_right); + method_call mc = new method_call(dnode, new expression_list()); + mc.visit(this); + return; + } + return_value(expression_value_reciving(id_right, sil, en, true)); + return; + } + case motivation.semantic_node_reciving: + { + if (sil.FirstOrDefault().sym_info is function_node && (sil.FirstOrDefault().sym_info as function_node).is_extension_method) + has_property(ref sil); + return_semantic_value(expression_value_reciving(id_right, sil, en, true)); + return; + } + } + throw new CompilerInternalError("Invalid motivation."); + } + + private void dot_node_as_dot_node_dot_ident(SyntaxTree.dot_node left_dot, SyntaxTree.ident id_right, + motivation mot) + { + semantic_node sn = convert_semantic_strong(left_dot); + switch (sn.general_node_type) + { + case general_node_type.expression: + { + expression_node en = (expression_node)sn; + dot_node_as_expression_dot_ident(en, id_right, mot, left_dot); + return; + } + case general_node_type.namespace_node: + { + namespace_node nn = (namespace_node)sn; + dot_node_as_namespace_ident(nn, id_right, mot); + return; + } + case general_node_type.type_node: + { + type_node tn = (type_node)sn; + dot_node_as_type_ident(tn, id_right, mot); + return; + } + case general_node_type.unit_node: + { + throw new CompilerInternalError("Not supported"); + } + } + throw new CompilerInternalError("Invalid left dot node kind"); + } + + private void dot_node_as_dot_node_dot_template_ident(SyntaxTree.dot_node left_dot, SyntaxTree.ident_with_templateparams template_id_right, + motivation mot) + { + semantic_node sn = convert_semantic_strong(left_dot); + ident id_right = template_id_right.name as ident; + switch (sn.general_node_type) + { + case general_node_type.expression: + { + expression_node en = (expression_node)sn; + dot_node_as_expression_dot_template_ident(en, template_id_right, mot, left_dot); + return; + } + case general_node_type.namespace_node: + { + namespace_node nn = (namespace_node)sn; + dot_node_as_namespace_ident(nn, id_right, mot); + return; + } + case general_node_type.type_node: + { + type_node tn = (type_node)sn; + dot_node_as_type_ident(tn, id_right, mot); + return; + } + case general_node_type.unit_node: + { + throw new CompilerInternalError("Not supported"); + } + } + throw new CompilerInternalError("Invalid left dot node kind"); + } + + private bool can_convert_to_method_call(ref List sil) + { + List tmp_list = new List(sil); + foreach (SymbolInfo tmp_si in tmp_list) + { + if (tmp_si.sym_info is function_node && !(tmp_si.sym_info as function_node).is_extension_method && (tmp_si.sym_info as function_node).polymorphic_state != SemanticTree.polymorphic_state.ps_static + && !(tmp_si.sym_info is common_method_node && (tmp_si.sym_info as common_method_node).is_constructor) && (tmp_si.sym_info as function_node).return_value_type != null + && !(tmp_si.sym_info is compiled_constructor_node)) + return false; + } + foreach (SymbolInfo tmp_si in tmp_list) + { + if (tmp_si.sym_info is function_node && (tmp_si.sym_info as function_node).is_extension_method && !has_property(ref sil) + || tmp_si.sym_info is common_method_node && (tmp_si.sym_info as common_method_node).is_constructor + || tmp_si.sym_info is compiled_constructor_node) + return true; + } + return false; + } + + public override void visit(SyntaxTree.dot_node _dot_node) + { + var mot = motivation_keeper.motivation; + + SyntaxTree.ident id_left = _dot_node.left as SyntaxTree.ident; + SyntaxTree.ident id_right = _dot_node.right as SyntaxTree.ident; + if (_dot_node.right is ident_with_templateparams) + id_right = (_dot_node.right as ident_with_templateparams).name as ident; + + // SSM 18.08.16 - пробуем обработать захват enn.ii в yieldах где enn - поле класса и нуждается в переименовании + // Так же ниже делает lroman + if (_dot_node.left is yield_unknown_ident) + { + var yui = (yield_unknown_ident)_dot_node.left; + var av = ProcessUnknownIdent(yui); + var dn = new dot_node(av, _dot_node.right,yui.source_context); + visit(dn); + return; + } + + //lroman + if (_dot_node.left is closure_substituting_node) + { + var left = (closure_substituting_node)_dot_node.left; + var dotNodeToVisit = new dot_node(left.substitution, _dot_node.right); // Подменить dot_node в этот момент на этапе семантики + dotNodeToVisit.Parent = _dot_node.Parent; // SSM 01.06.19 + visit(dotNodeToVisit); + return; + } + motivation_keeper.reset(); // SSM перенес сюда сверху - bug fix #263 + + if (id_left != null) + { + if (_dot_node.right is ident_with_templateparams) + { + dot_node_as_ident_dot_template_ident(id_left, _dot_node.right as ident_with_templateparams, mot); + return; + } + if (id_left.name != null && id_left.name.IndexOf('.') != -1) + { + var arr = id_left.name.Split('.'); + var dotNodeToVisit = new dot_node(new ident(id_left.name.Substring(0, id_left.name.LastIndexOf('.')), id_left.source_context), new ident(arr[arr.Length-1],id_left.source_context)); + + visit(new dot_node(dotNodeToVisit, id_right, _dot_node.source_context)); + return; + } + if (id_left is inherited_ident) + inherited_ident_processing = true; + dot_node_as_ident_dot_ident(id_left, id_right, mot); + inherited_ident_processing = false; + return; + } + else + { + SyntaxTree.ident_with_templateparams iwt = _dot_node.left as SyntaxTree.ident_with_templateparams; + if (iwt != null) + { + var ret_node = ret.visit((SyntaxTree.syntax_tree_node)iwt); + if (ret_node is type_node) + { + type_node tn = ret.visit((SyntaxTree.syntax_tree_node)iwt) as type_node; + dot_node_as_type_ident(tn, id_right, mot); + return; + } + } + SyntaxTree.dot_node left_dot = _dot_node.left as SyntaxTree.dot_node; + if (left_dot != null) + { + if (_dot_node.right is ident_with_templateparams) + { + dot_node_as_dot_node_dot_template_ident(left_dot, _dot_node.right as ident_with_templateparams, mot); + return; + } + dot_node_as_dot_node_dot_ident(left_dot, id_right, mot); + return; + } + expression_node en = convert_strong(_dot_node.left); + if (_dot_node.right is ident_with_templateparams) + { + dot_node_as_expression_dot_template_ident(en, _dot_node.right as ident_with_templateparams, mot, _dot_node.left); + return; + } + dot_node_as_expression_dot_ident(en, id_right, mot, _dot_node.left); + return; + } + } + + private SyntaxTree.ident ConvertOperatorNameToIdent(SyntaxTree.ident opname) + { + if (opname is SyntaxTree.operator_name_ident) + { + SyntaxTree.ident id = new SyntaxTree.ident(name_reflector.get_name((opname as SyntaxTree.operator_name_ident).operator_type)); + id.source_context = opname.source_context; + return id; + } + return opname; + } + + + + private void visit_method_name(SyntaxTree.method_name _method_name) + { + convertion_data_and_alghoritms.check_node_parser_error(_method_name); + convertion_data_and_alghoritms.check_node_parser_error(_method_name.meth_name); + common_type_node tp = null; + definition_node def_temp = null; + SyntaxTree.template_type_name ttn = null; + bool is_operator = _method_name.meth_name is SyntaxTree.operator_name_ident; + if (is_operator && context.converted_type != null && context.converted_type.IsInterface) + AddError(get_location(_method_name), "OPERATORS_IN_INTERFACES_NOT_ALLOWED"); + SyntaxTree.Operators op = PascalABCCompiler.SyntaxTree.Operators.Undefined; + if(is_operator) + op=(_method_name.meth_name as SyntaxTree.operator_name_ident).operator_type; + _method_name.meth_name = ConvertOperatorNameToIdent(_method_name.meth_name); + bool explicit_impl = false; + if ((context.converting_block() != block_type.namespace_block) && (_method_name.class_name != null)) + { + explicit_impl = true; + } + if (is_operator && op==SyntaxTree.Operators.AddressOf && SemanticRules.AddressOfOperatorNonOverloaded) + { + AddError(get_location(_method_name.meth_name), "NOT_OVERLOADED_OPERATOR"); + } + bool common_extension_meth = false; + if (_method_name.class_name != null) + { + convertion_data_and_alghoritms.check_node_parser_error(_method_name.class_name); + location loc_type_name = get_location(_method_name.class_name); + ttn = _method_name.class_name as SyntaxTree.template_type_name; + int num_template_args = 0; + if (ttn != null) + { + num_template_args = ttn.template_args.idents.Count; + } + common_type_node current_conv_type = context.converted_type; + def_temp = context.enter_in_type_method(_method_name, _method_name.class_name.name, loc_type_name, num_template_args); + if (explicit_impl) + { + context.converted_type = current_conv_type; + if (def_temp is type_node && (def_temp as type_node).IsInterface) + { + context.converted_explicit_interface_type = def_temp as type_node; + List sil = context.converted_explicit_interface_type.find_in_type(_method_name.meth_name.name); + if (sil == null) + AddError(new UndefinedNameReference(_method_name.meth_name.name, get_location(_method_name.meth_name))); + } + else + AddError(new OnlyProcedureNameAllowedInClassFunctionDefinition(_method_name.class_name.name, + get_location(_method_name.class_name))); + } + tp = def_temp as common_type_node; + template_class tc = def_temp as template_class; + //SyntaxTree.template_type_name ttn = _method_name.class_name as SyntaxTree.template_type_name; + if (ttn != null && !(def_temp is compiled_type_node)) + { + int count; + if (tp == null) + { + if (tc != null) + { + if (tc.is_synonym) + { + AddError(loc_type_name, "CAN_NOT_DEFINE_METHOD_OF_TEMPLATE_TYPE_SYNONYM"); + } + SyntaxTree.class_definition cl_def = tc.type_dec.type_def as SyntaxTree.class_definition; + count = cl_def.template_args.idents.Count; + if (count != ttn.template_args.idents.Count) + { + AddError(get_location(ttn), "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", tc.name, count); + } + for (int i = 0; i < count; ++i) + { + if (string.Compare(cl_def.template_args.idents[i].name, ttn.template_args.idents[i].name, true) != 0) + { + AddError(get_location(ttn.template_args.idents[i]), "PARAMETER_{0}_MUST_BE_NAMED_{1}", i + 1, cl_def.template_args.idents[i].name); + } + } + _method_name.class_name = new SyntaxTree.ident(ttn.name); + _method_name.class_name.source_context = ttn.source_context; + return; + } + AddError(get_location(ttn), "COULD_NOT_DEFINE_GENERIC_FUNCTION_OF_COMPILED_TYPE"); + } + if (tp.generic_params == null) + { + AddError(get_location(ttn), "{0}_IS_NOT_TEMPLATE_CLASS", tp.PrintableName); + } + count = tp.generic_params.Count; + if (count != ttn.template_args.idents.Count) + { + AddError(get_location(ttn), "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", tp.PrintableName, count); + } + for (int i = 0; i < count; ++i) + { + if (string.Compare(tp.generic_params[i].name, ttn.template_args.idents[i].name, true) != 0) + { + AddError(get_location(ttn.template_args.idents[i]), "PARAMETER_{0}_MUST_BE_NAMED_{1}", i + 1, tp.generic_params[i].name); + } + } + } + else + { + if (tp != null && tp.is_generic_type_definition) + { + AddError(get_location(_method_name.class_name), "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", tp.PrintableName, tp.generic_params.Count); + } + if (tc != null) + { + var td = tc.type_dec.type_def as SyntaxTree.class_definition; + var cnt = 0; + if (td != null) + cnt = td.template_args.idents.Count; + var td1 = tc.type_dec.type_def as SyntaxTree.template_type_reference; + if (td1 != null) + cnt = td1.params_list.Count; + AddError(get_location(_method_name.class_name), "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", tc.name, cnt); + } + } + //(ds)проверяем на компилированный тип + if (!(def_temp is compiled_type_node)) + { + //(ssyy) проверяем на шаблон + if (tp == null) + { + return; + } + if (tp is compiled_generic_instance_type_node || tp is common_generic_instance_type_node) + AddError(get_location(_method_name), "EXTENSION_METHOD_FOR_GENERIC_INSTANCES"); + List sil = tp.scope.FindOnlyInScope(_method_name.meth_name.name); + + if (tp.original_template == null && ((sil == null && this._compiled_unit.namespaces.IndexOf(tp.comprehensive_namespace) == -1) || (sil != null && this._compiled_unit.namespaces.IndexOf(tp.comprehensive_namespace) == -1)) && !explicit_impl) + { + + if (def_temp is common_type_node) + { + common_extension_meth = true; + common_type_node ctn = def_temp as common_type_node; + if (ctn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.array_wrapper || + ctn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.set_type || + ctn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.base_set_type || + ctn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.binary_file || + ctn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.text_file || + ctn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.typed_file) + AddError(get_location(_method_name), "NO_METHOD_{0}_IN_CLASS_{1}", _method_name.meth_name.name, tp.PrintableName); + } + else + AddError(get_location(_method_name), "NO_METHOD_{0}_IN_CLASS_{1}", _method_name.meth_name.name, tp.PrintableName); + } + } + else if (def_temp as compiled_type_node == SystemLibrary.SystemLibrary.void_type) + AddError(get_location(_method_name.class_name), "VOID_NOT_VALID"); + } + else + { + if (is_operator && context.converted_type == null && context.converted_template_type == null && !(current_function_header != null && current_function_header.proc_attributes != null && has_extensionmethod_attr(current_function_header.proc_attributes.proc_attributes)) /*&& !(current_function_header != null && current_function_header.template_args != null && current_function_header.template_args.idents.Count > 0)*/) + { + AddError(get_location(_method_name), "OVERLOADED_OPERATOR_MUST_BE_STATIC_FUNCTION"); + } + + } + convertion_data_and_alghoritms.check_node_parser_error(_method_name.meth_name); + location loc_name = get_location(_method_name.meth_name); + context.extension_method = common_extension_meth; + if (LambdaHelper.IsLambdaName(_method_name.meth_name) && lambdaProcessingState != LambdaProcessingState.ClosuresProcessingVisitGeneratedClassesPhase) //lroman// + { + if (lambdaProcessingState == LambdaProcessingState.None && + context.converting_block() == block_type.namespace_block) + { + context.create_function(_method_name.meth_name.name, loc_name); + } + else + { + var addSymbol = (lambdaProcessingState == LambdaProcessingState.TypeInferencePhase && + LambdaHelper.IsAuxiliaryLambdaName(_method_name.meth_name)) || lambdaProcessingState == LambdaProcessingState.FinishPhase; + context.create_lambda_function(_method_name.meth_name.name, loc_name, addSymbol, context.CurrentScope); + } + } + else + { + if (current_function_header != null && current_function_header.proc_attributes != null && has_extensionmethod_attr(current_function_header.proc_attributes.proc_attributes)) + context.create_function(_method_name.meth_name.name, loc_name, false); + else + { + if (!explicit_impl) + context.create_function(_method_name.meth_name.name, loc_name); + else + context.create_function(context.converted_explicit_interface_type.BaseFullName+"."+_method_name.meth_name.name, loc_name); + } + } + context.extension_method = false; + context.top_function.IsOperator = is_operator; + if (ttn != null && def_temp is compiled_type_node) + { + if (!explicit_impl) + visit_generic_params(context.top_function, ttn.template_args.idents); + else + { + List instance_params = new List(); + foreach (ident id in ttn.template_args.idents) + { + SymbolInfo si = context.find_first(id.name); + if (si == null) + AddError(new UndefinedNameReference(id.name, get_location(id))); + if (!(si.sym_info is type_node)) + AddError(new ExpectedType(get_location(id))); + instance_params.Add(si.sym_info as type_node); + } + if (!context.converted_explicit_interface_type.IsInterface) + AddError(get_location(ttn), "INTERFACE_EXPECTED"); + type_node inst_tn = context.converted_explicit_interface_type.get_instance(instance_params); + bool found = false; + if (context.converted_type.ImplementingInterfaces.Count > 0) + { + foreach (type_node interf in context.converted_type.ImplementingInterfaces) + { + if (interf == inst_tn) + { + found = true; + break; + } + } + } + if (!found) + AddError(get_location(ttn),"CLASS_NOT_IMPLEMENT_THIS_INTERFACE"); + } + } + //context.top_function.IsOperator = _method_name.meth_name is SyntaxTree.operator_name_ident; + + } + + public override void visit(SyntaxTree.method_name _method_name) + { + visit_method_name(_method_name); + } + + private void is_case_variant_intersection_with_another(switch_node sn, int_const_node defined_const, location curloc) + { + foreach (case_variant_node cv in sn.case_variants) + { + foreach (int_const_node cn in cv.case_constants) + { + if (cn.constant_value == defined_const.constant_value) + { + AddError(curloc, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_ANOTHER"); + } + } + foreach (case_range_node cr in cv.case_ranges) + { + if ((defined_const.constant_value <= cr.high_bound.constant_value) && + (defined_const.constant_value >= cr.lower_bound.constant_value)) + { + AddError(curloc, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_DIAPASON"); + } + } + } + } + + private void is_case_range_intersection_with_another(switch_node sn, case_range_node defined_range, location curloc) + { + foreach (case_variant_node cv in sn.case_variants) + { + foreach (int_const_node icn in cv.case_constants) + { + if ((icn.constant_value >= defined_range.lower_bound.constant_value) && + (icn.constant_value <= defined_range.high_bound.constant_value)) + { + AddError(curloc, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_DIAPASON"); + } + } + foreach (case_range_node cr in cv.case_ranges) + { + if ((cr.lower_bound.constant_value <= defined_range.high_bound.constant_value) && + (cr.lower_bound.constant_value >= defined_range.lower_bound.constant_value)) + { + AddError(curloc, "CASE_DIAPASON_VARIANT_INTERSECTION"); + } + if ((cr.high_bound.constant_value <= defined_range.high_bound.constant_value) && + (cr.high_bound.constant_value >= defined_range.lower_bound.constant_value)) + { + AddError(curloc, "CASE_DIAPASON_VARIANT_INTERSECTION"); + } + } + } + } + + private string_const_node convert_string_const_to_switch(expression_node switch_expr, location loc) + { + if (switch_expr is string_const_node) + return switch_expr as string_const_node; + string_const_node scn = null; + if (switch_expr is static_compiled_variable_reference && (switch_expr as static_compiled_variable_reference).var.compiled_field.IsLiteral) + scn = new string_const_node((string)(switch_expr as static_compiled_variable_reference).var.compiled_field.GetRawConstantValue(), loc); + if (scn == null) + { + AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); + } + return scn; + } + + private long_const_node convert_long_const_to_switch(expression_node switch_expr, location loc) + { + convertion_data_and_alghoritms.convert_type(switch_expr, SystemLibrary.SystemLibrary.int64_type, loc); + if (switch_expr is long_const_node) + return switch_expr as long_const_node; + //switch_expr = convertion_data_and_alghoritms.create_simple_function_call(oti.value_to_int, + // loc, switch_expr); + long_const_node icn = null;//switch_expr as constant_node; + + if (switch_expr is byte_const_node) + icn = new long_const_node((switch_expr as byte_const_node).constant_value, loc); + else if (switch_expr is sbyte_const_node) + icn = new long_const_node((long)((switch_expr as sbyte_const_node).constant_value), loc); + else if (switch_expr is short_const_node) + icn = new long_const_node((long)((switch_expr as short_const_node).constant_value), loc); + else if (switch_expr is ushort_const_node) + icn = new long_const_node((long)((switch_expr as ushort_const_node).constant_value), loc); + else if (switch_expr is uint_const_node) + icn = new long_const_node((long)((switch_expr as uint_const_node).constant_value),loc); + else if (switch_expr is int_const_node) + icn = new long_const_node((long)((switch_expr as int_const_node).constant_value),loc); + else if (switch_expr is ulong_const_node) + icn = new long_const_node((long)((switch_expr as ulong_const_node).constant_value), loc); + else if (switch_expr is enum_const_node) + icn = new long_const_node((switch_expr as enum_const_node).constant_value, loc); + else if (switch_expr is static_compiled_variable_reference && (switch_expr as static_compiled_variable_reference).var.compiled_field.IsLiteral) + icn = new long_const_node((long)(switch_expr as static_compiled_variable_reference).var.compiled_field.GetRawConstantValue(), loc); + //учти здесь модет быть и long! + //-DarkStar Add + if (icn == null) + { + AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); + } + return icn; + } + + private ulong_const_node convert_ulong_const_to_switch(expression_node switch_expr, location loc) + { + convertion_data_and_alghoritms.convert_type(switch_expr, SystemLibrary.SystemLibrary.uint64_type, loc); + if (switch_expr is ulong_const_node) + return switch_expr as ulong_const_node; + //switch_expr = convertion_data_and_alghoritms.create_simple_function_call(oti.value_to_int, + // loc, switch_expr); + ulong_const_node icn = null;//switch_expr as constant_node; + + if (switch_expr is byte_const_node) + icn = new ulong_const_node((switch_expr as byte_const_node).constant_value, loc); + else if (switch_expr is sbyte_const_node) + icn = new ulong_const_node((ulong)((switch_expr as sbyte_const_node).constant_value), loc); + else if (switch_expr is short_const_node) + icn = new ulong_const_node((ulong)((switch_expr as short_const_node).constant_value), loc); + else if (switch_expr is ushort_const_node) + icn = new ulong_const_node((ulong)((switch_expr as ushort_const_node).constant_value), loc); + else if (switch_expr is int_const_node) + icn = new ulong_const_node((ulong)((switch_expr as int_const_node).constant_value),loc); + else if (switch_expr is uint_const_node) + icn = new ulong_const_node((ulong)((switch_expr as uint_const_node).constant_value), loc); + else if (switch_expr is long_const_node) + icn = new ulong_const_node((ulong)((switch_expr as long_const_node).constant_value),loc); + else if (switch_expr is char_const_node) + icn = new ulong_const_node((ulong)((switch_expr as char_const_node).constant_value), loc); + else if (switch_expr is enum_const_node) + icn = new ulong_const_node((ulong)((switch_expr as enum_const_node).constant_value), loc); + else if (switch_expr is static_compiled_variable_reference && (switch_expr as static_compiled_variable_reference).var.compiled_field.IsLiteral) + icn = new ulong_const_node((ulong)(switch_expr as static_compiled_variable_reference).var.compiled_field.GetRawConstantValue(), loc); + //учти здесь модет быть и long! + //-DarkStar Add + if (icn == null) + { + AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); + } + return icn; + } + + private int_const_node convert_const_to_switch(expression_node switch_expr, + ordinal_type_interface oti, type_node case_expr_type, location loc) + { + convertion_data_and_alghoritms.convert_type(switch_expr, case_expr_type, loc); + if (switch_expr is int_const_node) + return switch_expr as int_const_node; + //switch_expr = convertion_data_and_alghoritms.create_simple_function_call(oti.value_to_int, + // loc, switch_expr); + int_const_node icn = null;//switch_expr as constant_node; + + if (switch_expr is byte_const_node) + icn = new int_const_node((switch_expr as byte_const_node).constant_value, loc); + else if (switch_expr is sbyte_const_node) + icn = new int_const_node(Convert.ToInt32((switch_expr as sbyte_const_node).constant_value), loc); + else if (switch_expr is short_const_node) + icn = new int_const_node(Convert.ToInt32((switch_expr as short_const_node).constant_value), loc); + else if (switch_expr is ushort_const_node) + icn = new int_const_node(Convert.ToInt32((switch_expr as ushort_const_node).constant_value), loc); + else if (switch_expr is bool_const_node) + icn = new int_const_node(Convert.ToInt32((switch_expr as bool_const_node).constant_value), loc); + else if (switch_expr is char_const_node) + icn = new int_const_node(Convert.ToInt32((switch_expr as char_const_node).constant_value), loc); + else if (switch_expr is enum_const_node) + icn = new int_const_node((switch_expr as enum_const_node).constant_value, loc); + else if (switch_expr is static_compiled_variable_reference && (switch_expr as static_compiled_variable_reference).var.compiled_field.IsLiteral) + icn = new int_const_node((int)(switch_expr as static_compiled_variable_reference).var.compiled_field.GetRawConstantValue(), loc); + //учти здесь модет быть и long! + //-DarkStar Add + if (icn == null) + { + AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); + } + return icn; + } + + //TODO: Добавить приведение типов. + public override void visit(SyntaxTree.case_node _case_node) + { + convertion_data_and_alghoritms.check_node_parser_error(_case_node); + switch_node sn = new switch_node(get_location(_case_node)); + expression_node en = convert_strong(_case_node.param); + if (en is typed_expression) en = convert_typed_expression_to_function_call(en as typed_expression); + type_node case_expr_type = en.type; + + internal_interface ii = en.type.get_internal_interface(internal_interface_kind.ordinal_interface); + if (ii == null) + { + // Попытка воспользоваться неявным преобразованием + if (convertion_data_and_alghoritms.can_convert_type(en, SystemLibrary.SystemLibrary.integer_type)) + en = convertion_data_and_alghoritms.convert_type(en, SystemLibrary.SystemLibrary.integer_type); + ii = en.type.get_internal_interface(internal_interface_kind.ordinal_interface); + if (ii == null) + if (convertion_data_and_alghoritms.can_convert_type(en, SystemLibrary.SystemLibrary.string_type)) + en = convertion_data_and_alghoritms.convert_type(en, SystemLibrary.SystemLibrary.string_type); + } + if (ii == null && en.type != SystemLibrary.SystemLibrary.string_type) + { + AddError(new OrdinalOrStringTypeExpected(en.location)); + } + if (ii != null && en.type != SystemLibrary.SystemLibrary.int64_type && en.type != SystemLibrary.SystemLibrary.uint64_type) + { + ordinal_type_interface oti = (ordinal_type_interface)ii; + en = convertion_data_and_alghoritms.create_simple_function_call(oti.value_to_int, en.location, en); + + sn.condition = en; + + foreach (SyntaxTree.case_variant cv in _case_node.conditions.variants) + { + convertion_data_and_alghoritms.check_node_parser_error(cv); + case_variant_node sem_cv = new case_variant_node(get_location(cv)); + sn.case_variants.AddElement(sem_cv); + foreach (SyntaxTree.expression expr in cv.conditions.expressions) + { + convertion_data_and_alghoritms.check_node_parser_error(expr); + SyntaxTree.diapason_expr diap = expr as SyntaxTree.diapason_expr; + if (diap == null) + { + expression_node cn = convert_strong(expr); + int_const_node icn = convert_const_to_switch(cn, oti, case_expr_type, get_location(expr)); + is_case_variant_intersection_with_another(sn, icn, get_location(expr)); + sem_cv.case_constants.AddElement(icn); + } + else + { + convertion_data_and_alghoritms.check_node_parser_error(diap.left); + expression_node left = convert_strong(diap.left); + int_const_node icn_left = convert_const_to_switch(left, oti, case_expr_type, get_location(diap.left)); + + convertion_data_and_alghoritms.check_node_parser_error(diap.right); + expression_node right = convert_strong(diap.right); + int_const_node icn_right = convert_const_to_switch(right, oti, case_expr_type, get_location(diap.right)); + //ssyy + if (icn_left.constant_value > icn_right.constant_value) + { + AddError(get_location(diap.right), "LEFT_RANGE_GREATER_THEN_RIGHT"); + } + //\ssyy + case_range_node crn = new case_range_node(icn_left, icn_right, get_location(diap)); + is_case_range_intersection_with_another(sn, crn, get_location(expr)); + sem_cv.case_ranges.AddElement(crn); + } + } + context.enter_code_block_with_bind(); + CheckToEmbeddedStatementCannotBeADeclaration(cv.exec_if_true); + statement_node stmn = convert_strong(cv.exec_if_true); + context.leave_code_block(); + sem_cv.case_statement = stmn; + //sn.case_variants.AddElement(sem_cv); + } + context.enter_code_block_with_bind(); + statement_node else_statement = convert_weak(_case_node.else_statement); + context.leave_code_block(); + sn.default_statement = else_statement; + return_value(sn); + } + else if (en.type == SystemLibrary.SystemLibrary.string_type) + { + if_node main_ifn = null; + if_node ifn = null; + compiled_function_node str_eq_meth = SystemLibrary.SystemLibrary.string_type.find_first_in_type("=").sym_info as compiled_function_node; + Dictionary case_constants = new Dictionary(); + foreach (SyntaxTree.case_variant cv in _case_node.conditions.variants) + { + convertion_data_and_alghoritms.check_node_parser_error(cv); + location loc = get_location(cv); + expression_node eq_node = null; + List eq_calls = new List(); + foreach (SyntaxTree.expression expr in cv.conditions.expressions) + { + expression_node cn = convert_strong(expr); + if (cn.type == SystemLibrary.SystemLibrary.char_type) + cn = convertion_data_and_alghoritms.convert_type(cn, SystemLibrary.SystemLibrary.string_type); + if (cn.type != SystemLibrary.SystemLibrary.string_type) + AddError(new CanNotConvertTypes(cn, cn.type, SystemLibrary.SystemLibrary.string_type, cn.location)); + string_const_node scn = convert_string_const_to_switch(cn, cn.location); + if (!case_constants.ContainsKey(scn.constant_value)) + case_constants.Add(scn.constant_value, scn.constant_value); + else + AddError(cn.location, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_ANOTHER"); + compiled_static_method_call eq_call = new compiled_static_method_call(str_eq_meth, cn.location); + eq_call.parameters.AddElement(en); + eq_call.parameters.AddElement(cn); + eq_calls.Add(eq_call); + } + foreach (compiled_static_method_call eq_call in eq_calls) + { + if (eq_node == null) + eq_node = eq_call; + else + eq_node = new basic_function_call(SystemLibrary.SystemLibrary.bool_or as basic_function_node, null, eq_node, eq_call); + } + context.enter_code_block_with_bind(); + CheckToEmbeddedStatementCannotBeADeclaration(cv.exec_if_true); + statement_node stmn = convert_strong(cv.exec_if_true); + context.leave_code_block(); + if (ifn != null) + { + ifn.else_body = new if_node(eq_node, stmn, null, loc); + ifn = ifn.else_body as if_node; + } + else + ifn = new if_node(eq_node, stmn, null, loc); + if (main_ifn == null) + main_ifn = ifn; + } + context.enter_code_block_with_bind(); + CheckToEmbeddedStatementCannotBeADeclaration(_case_node.else_statement); + statement_node else_statement = convert_weak(_case_node.else_statement); + context.leave_code_block(); + if (ifn == null) + { + ifn = new if_node(en, new statements_list(null), null, get_location(_case_node)); + main_ifn = ifn; + } + ifn.else_body = else_statement; + return_value(main_ifn); + } + else if (en.type == SystemLibrary.SystemLibrary.int64_type) + { + if_node main_ifn = null; + if_node ifn = null; + basic_function_node int64_eq_meth = SystemLibrary.SystemLibrary.int64_type.find_first_in_type("=", true).sym_info as basic_function_node; + + Dictionary case_constants = new Dictionary(); + foreach (SyntaxTree.case_variant cv in _case_node.conditions.variants) + { + convertion_data_and_alghoritms.check_node_parser_error(cv); + location loc = get_location(cv); + expression_node eq_node = null; + List eq_calls = new List(); + foreach (SyntaxTree.expression expr in cv.conditions.expressions) + { + SyntaxTree.diapason_expr diap = expr as SyntaxTree.diapason_expr; + if (diap == null) + { + expression_node cn = convert_strong(expr); + long_const_node scn = convert_long_const_to_switch(cn, cn.location); + if (!case_constants.ContainsKey(scn.constant_value)) + case_constants.Add(scn.constant_value, scn.constant_value); + else + AddError(cn.location, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_ANOTHER"); + basic_function_call eq_call = new basic_function_call(int64_eq_meth, cn.location); + eq_call.parameters.AddElement(en); + eq_call.parameters.AddElement(scn); + eq_calls.Add(eq_call); + } + else + { + expression_node left_cn = convert_strong(diap.left); + expression_node right_cn = convert_strong(diap.right); + long_const_node left_scn = convert_long_const_to_switch(left_cn, left_cn.location); + long_const_node right_scn = convert_long_const_to_switch(right_cn, right_cn.location); + if (left_scn.constant_value > right_scn.constant_value) + { + AddError(get_location(diap.right), "LEFT_RANGE_GREATER_THEN_RIGHT"); + } + basic_function_node int64_greq_meth = SystemLibrary.SystemLibrary.int64_type.find_first_in_type(">=", true).sym_info as basic_function_node; + basic_function_node int64_leq_meth = SystemLibrary.SystemLibrary.int64_type.find_first_in_type("<=", true).sym_info as basic_function_node; + basic_function_call greq_call = new basic_function_call(int64_greq_meth, left_cn.location); + greq_call.parameters.AddElement(en); + greq_call.parameters.AddElement(left_scn); + basic_function_call leq_call = new basic_function_call(int64_leq_meth, right_cn.location); + leq_call.parameters.AddElement(en); + leq_call.parameters.AddElement(right_scn); + basic_function_node in_diap_meth = SystemLibrary.SystemLibrary.bool_type.find_first_in_type("and", true).sym_info as basic_function_node; + basic_function_call in_diap_call = new basic_function_call(in_diap_meth, left_cn.location); + in_diap_call.parameters.AddElement(greq_call); + in_diap_call.parameters.AddElement(leq_call); + eq_calls.Add(in_diap_call); + } + } + foreach (basic_function_call eq_call in eq_calls) + { + if (eq_node == null) + eq_node = eq_call; + else + eq_node = new basic_function_call(SystemLibrary.SystemLibrary.bool_or as basic_function_node, null, eq_node, eq_call); + } + context.enter_code_block_with_bind(); + CheckToEmbeddedStatementCannotBeADeclaration(cv.exec_if_true); + statement_node stmn = convert_strong(cv.exec_if_true); + context.leave_code_block(); + if (ifn != null) + { + ifn.else_body = new if_node(eq_node, stmn, null, loc); + ifn = ifn.else_body as if_node; + } + else + ifn = new if_node(eq_node, stmn, null, loc); + if (main_ifn == null) + main_ifn = ifn; + } + context.enter_code_block_with_bind(); + CheckToEmbeddedStatementCannotBeADeclaration(_case_node.else_statement); + statement_node else_statement = convert_weak(_case_node.else_statement); + context.leave_code_block(); + if (ifn == null) + { + ifn = new if_node(en, new statements_list(null), null, get_location(_case_node)); + main_ifn = ifn; + } + ifn.else_body = else_statement; + return_value(main_ifn); + } + else + { + if_node main_ifn = null; + if_node ifn = null; + basic_function_node uint64_eq_meth = SystemLibrary.SystemLibrary.uint64_type.find_first_in_type("=", true).sym_info as basic_function_node; + Dictionary case_constants = new Dictionary(); + foreach (SyntaxTree.case_variant cv in _case_node.conditions.variants) + { + convertion_data_and_alghoritms.check_node_parser_error(cv); + location loc = get_location(cv); + expression_node eq_node = null; + List eq_calls = new List(); + foreach (SyntaxTree.expression expr in cv.conditions.expressions) + { + SyntaxTree.diapason_expr diap = expr as SyntaxTree.diapason_expr; + if (diap == null) + { + expression_node cn = convert_strong(expr); + ulong_const_node scn = convert_ulong_const_to_switch(cn, cn.location); + if (!case_constants.ContainsKey(scn.constant_value)) + case_constants.Add(scn.constant_value, scn.constant_value); + else + AddError(cn.location, "CASE_CONSTANT_VARIANT_COINCIDE_WITH_ANOTHER"); + basic_function_call eq_call = new basic_function_call(uint64_eq_meth, cn.location); + eq_call.parameters.AddElement(en); + eq_call.parameters.AddElement(scn); + eq_calls.Add(eq_call); + } + else + { + expression_node left_cn = convert_strong(diap.left); + expression_node right_cn = convert_strong(diap.right); + ulong_const_node left_scn = convert_ulong_const_to_switch(left_cn, left_cn.location); + ulong_const_node right_scn = convert_ulong_const_to_switch(right_cn, right_cn.location); + if (left_scn.constant_value > right_scn.constant_value) + { + AddError(get_location(diap.right), "LEFT_RANGE_GREATER_THEN_RIGHT"); + } + basic_function_node uint64_greq_meth = SystemLibrary.SystemLibrary.uint64_type.find_first_in_type(">=", true).sym_info as basic_function_node; + basic_function_node uint64_leq_meth = SystemLibrary.SystemLibrary.uint64_type.find_first_in_type("<=", true).sym_info as basic_function_node; + basic_function_call greq_call = new basic_function_call(uint64_greq_meth, left_cn.location); + greq_call.parameters.AddElement(en); + greq_call.parameters.AddElement(left_scn); + basic_function_call leq_call = new basic_function_call(uint64_leq_meth, right_cn.location); + leq_call.parameters.AddElement(en); + leq_call.parameters.AddElement(right_scn); + basic_function_node in_diap_meth = SystemLibrary.SystemLibrary.bool_type.find_first_in_type("and", true).sym_info as basic_function_node; + basic_function_call in_diap_call = new basic_function_call(in_diap_meth, left_cn.location); + in_diap_call.parameters.AddElement(greq_call); + in_diap_call.parameters.AddElement(leq_call); + eq_calls.Add(in_diap_call); + } + } + foreach (basic_function_call eq_call in eq_calls) + { + if (eq_node == null) + eq_node = eq_call; + else + eq_node = new basic_function_call(SystemLibrary.SystemLibrary.bool_or as basic_function_node, null, eq_node, eq_call); + } + context.enter_code_block_with_bind(); + CheckToEmbeddedStatementCannotBeADeclaration(cv.exec_if_true); + statement_node stmn = convert_strong(cv.exec_if_true); + context.leave_code_block(); + if (ifn != null) + { + ifn.else_body = new if_node(eq_node, stmn, null, loc); + ifn = ifn.else_body as if_node; + } + else + ifn = new if_node(eq_node, stmn, null, loc); + if (main_ifn == null) + main_ifn = ifn; + } + context.enter_code_block_with_bind(); + CheckToEmbeddedStatementCannotBeADeclaration(_case_node.else_statement); + statement_node else_statement = convert_weak(_case_node.else_statement); + context.leave_code_block(); + if (ifn == null) + { + ifn = new if_node(en, new statements_list(null), null, get_location(_case_node)); + main_ifn = ifn; + } + ifn.else_body = else_statement; + return_value(main_ifn); + } + } + + public override void visit(SyntaxTree.case_variant _case_variant) + { + throw new NotSupportedError(get_location(_case_variant)); + } + + public override void visit(SyntaxTree.get_address _get_address) + { + expression_node exp = convert_strong(_get_address.address_of); + if (!exp.is_addressed) + { + AddError(exp.location, "CAN_NOT_GET_ADDRESS_FROM_EXPRESSION"); + } + expression_node res = new get_addr_node(exp, get_location(_get_address)); + return_value(res); + } + + public override void visit(SyntaxTree.hex_constant _hex_constant) + { + expression_node en = null; + if (_hex_constant.val <= Int32.MaxValue && _hex_constant.val >= Int32.MinValue) + en = new int_const_node((int)_hex_constant.val, get_location(_hex_constant)); + else + en = new long_const_node(_hex_constant.val, get_location(_hex_constant)); + return_value(en); + } + + private System.Collections.Generic.List ConvertDirectives(SyntaxTree.compilation_unit cu) + { + System.Collections.Generic.List list = new System.Collections.Generic.List(); + foreach (SyntaxTree.compiler_directive sncd in cu.compiler_directives) + { + list.Add(new compiler_directive(sncd.Name.text, sncd.Directive!=null?sncd.Directive.text:"", get_location(sncd), cu.file_name)); + } + return list; + } + + //TODO: Слить как нибудь два следующих метода. + public override void visit(SyntaxTree.program_module _program_module) + { + //MikhailoMMX Инициализация OpenMP + OpenMP.InitOpenMP(_program_module.compiler_directives, this, _program_module); + //\MikhailoMMX + + string namespace_name = ""; + location loc = get_location(_program_module); + if (_program_module.program_name != null) + { + namespace_name = _program_module.program_name.prog_name.name; + loc = get_location(_program_module.program_name.prog_name); + } + + + _compiled_unit = new common_unit_node(); + + _compiled_unit.compiler_directives = ConvertDirectives(_program_module); + + + SymbolTable.Scope[] used_units = build_referenced_units(referenced_units,true); + + _compiled_unit.scope = convertion_data_and_alghoritms.symbol_table.CreateUnitInterfaceScope(used_units, namespace_name == ""? System.IO.Path.GetFileName(CurrentDocument.file_name) : namespace_name); + + common_namespace_node cnsn = context.create_namespace(namespace_name, _compiled_unit, _compiled_unit.scope, loc); + cnsn.is_main = true; + + reset_for_interface(); + + UpdateUnitDefinitionItemForUnit(_compiled_unit); + hard_node_test_and_visit(_program_module.program_block); + context.check_labels(context.converted_namespace.labels); + + // frninja 28/04/16 - режем мусорные методы хелперы yield + { + var toRemove = cnsn.functions.Where(m => m.is_yield_helper).ToArray(); + foreach (var m in toRemove) + { + cnsn.functions.remove(m); + } + } + // end frninja + + common_namespace_function_node main_function = new common_namespace_function_node(compiler_string_consts.temp_main_function_name, + null, null, cnsn, null); + main_function.function_code = context.code; + context.apply_special_local_vars(main_function); + cnsn.functions.AddElement(main_function); + + context.leave_block(); +#if DEBUG + /*var fname = "C:\\st1.txt"; + if (System.IO.File.Exists(fname)) + System.IO.File.Delete(fname); + System.IO.File.AppendAllText(fname, SymbolTable.ToString());*/ +#endif + + _compiled_unit.main_function = main_function; + } + + + private void reset_for_interface() + { + body_exists = false; + } + + private bool check_for_dll_entry_module(List directives) + { + foreach (compiler_directive cd in directives) + { + if (string.Compare(cd.name,"apptype",true)==0 && string.Compare(cd.directive,"dll",true)==0) + return true; + } + return false; + } + + + + internal bool _is_interface_part = false; + public override void visit(SyntaxTree.unit_module _unit_module) + { + //MikhailoMMX Инициализация OpenMP + OpenMP.InitOpenMP(_unit_module.compiler_directives, this, _unit_module); + //\MikhailoMMX + + //current_document=new document(_unit_module.file_name); + string namespace_name = ""; + _is_interface_part = true; + location loc = null; + if (_unit_module.unit_name != null) + { + namespace_name = _unit_module.unit_name.idunit_name.name; + loc = get_location(_unit_module.unit_name.idunit_name); + if (namespace_name.ToLower() != System.IO.Path.GetFileNameWithoutExtension(_unit_module.file_name).ToLower()) + AddError(loc, "UNIT_NAME_MUST_BE_EQUAL_UNIT_FILE_NAME"); + } + + + _compiled_unit = new common_unit_node(_unit_module.unit_name.idunit_name.name); + assign_doc_info(_compiled_unit,_unit_module.unit_name); + _compiled_unit.compiler_directives = ConvertDirectives(_unit_module); + + SymbolTable.Scope[] used_units = build_referenced_units(referenced_units,true); + + _compiled_unit.scope = convertion_data_and_alghoritms.symbol_table.CreateUnitInterfaceScope(used_units, "unit " + namespace_name); + + common_namespace_node cnsn = context.create_namespace(namespace_name, _compiled_unit, _compiled_unit.scope, loc); + + _compiled_unit.add_unit_name_to_namespace(); + + if (check_for_dll_entry_module(_compiled_unit.compiler_directives)) + { + cnsn.is_main = true; + } + UpdateUnitDefinitionItemForUnit(_compiled_unit); + reset_for_interface(); + in_interface_part = false; + if (_unit_module.implementation_part != null) + in_interface_part = true; + hard_node_test_and_visit(_unit_module.interface_part); + if (_unit_module.implementation_part != null) + in_interface_part = false; + if (_unit_module.attributes != null) + make_attributes_for_declaration(_unit_module, _compiled_unit); + context.leave_interface_part(); + _is_interface_part = false; + /*#if DEBUG + var fname = "C:\\st1.txt"; + if (System.IO.File.Exists(fname)) + System.IO.File.Delete(fname); + SymbolTable.ToString(); + System.IO.File.AppendAllText(fname, SymbolTable.Print()); + //var st = new SymbolTableVisitor("C:\\st1.txt", SymbolTable); + //st.PrintProgam(true); + #endif*/ + + } + + public void convert_pabc_namespaces(syntax_namespace_node[] namespaces) + { + context.namespace_converted = true; + Dictionary dict = new Dictionary(); + foreach (syntax_namespace_node _syntax_namespace_node in namespaces) + { + _syntax_namespace_node.referenced_units.AddRange(referenced_units); + var names = _syntax_namespace_node.name.Split('.'); + SymTable.Scope scope = null; + SymTable.Scope parent_scope = context.CurrentScope; + for (int i = 0; i < names.Length; i++) + { + var si_list = context.CurrentScope.Find(names[i]); + if (si_list == null) + { + List top_scopes = new List(); + top_scopes.AddRange(build_referenced_units(_syntax_namespace_node.referenced_units, false)); + if (parent_scope != context.CurrentScope) + top_scopes.Add(parent_scope); + scope = convertion_data_and_alghoritms.symbol_table.CreateNamespaceScope(top_scopes.ToArray(), parent_scope); + common_namespace_node cmn = new common_namespace_node(null, _compiled_unit, names[i], scope, null); + + parent_scope.AddSymbol(names[i], new SymbolInfo(cmn)); + scope.AddSymbol(names[i], new SymbolInfo(cmn)); + if (i == names.Length - 1) + { + dict.Add(_syntax_namespace_node, cmn); + var unit_scope = context.converted_namespace.scope as SymTable.UnitInterfaceScope; + if (unit_scope.TopScopeArray != null) + for (int j = 0; j < unit_scope.TopScopeArray.Length; j++) + { + if (unit_scope.TopScopeArray[j] is NetHelper.NetScope) + { + NetHelper.NetScope netScope = unit_scope.TopScopeArray[j] as NetHelper.NetScope; + if (netScope.used_namespaces.Count > 0 && string.Compare(netScope.used_namespaces[0].namespace_name, _syntax_namespace_node.name, true) == 0) + { + unit_scope.TopScopeArray[j] = scope; + } + } + } + } + + } + else + { + foreach (SymbolInfo si in si_list) + if (si.sym_info is common_namespace_node) + { + common_namespace_node cmn = si.sym_info as common_namespace_node; + scope = cmn.scope; + if (!(scope is SymTable.NamespaceScope)) + { + if (i == names.Length - 1) + dict.Add(_syntax_namespace_node, cmn); + } + break; + } + else if (si.sym_info is compiled_namespace_node) + { + List top_scopes = new List(); + top_scopes.AddRange(build_referenced_units(_syntax_namespace_node.referenced_units, false)); + if (parent_scope != context.CurrentScope) + top_scopes.Add(parent_scope); + compiled_namespace_node cnn = si.sym_info as compiled_namespace_node; + if (cnn.common_namespace == null) + { + scope = convertion_data_and_alghoritms.symbol_table.CreateNamespaceScope(top_scopes.ToArray(), parent_scope); + common_namespace_node cmn = new common_namespace_node(null, _compiled_unit, names[i], scope, null); + cnn.common_namespace = cmn; + } + else + scope = cnn.common_namespace.scope; + if (i == names.Length - 1 && !dict.ContainsKey(_syntax_namespace_node)) + dict.Add(_syntax_namespace_node, cnn.common_namespace); + } + + if (scope == null) + AddError(get_location(_syntax_namespace_node), "NAMESPACE_REDECLARATION"); + } + parent_scope = scope; + } + } + + foreach (syntax_namespace_node _syntax_namespace_node in namespaces) + { + var cmn = dict[_syntax_namespace_node]; + List scopes = new List(); + SymTable.UnitInterfaceScope ns_scope = cmn.scope as SymTable.UnitInterfaceScope; + if (ns_scope.TopScopeArray != null) + scopes.AddRange(ns_scope.TopScopeArray); + foreach (unit_node un in _syntax_namespace_node.referenced_units) + { + if (un is namespace_unit_node) + { + var nun = un as namespace_unit_node; + var names = nun.namespace_name.namespace_name.Split('.'); + var si_list = context.CurrentScope.Find(names[0]); + if (si_list != null && si_list.FirstOrDefault().sym_info is common_namespace_node) + { + SymTable.Scope ns_scope2 = (si_list.FirstOrDefault().sym_info as common_namespace_node).scope; + for (int i = 1; i < names.Length; i++) + { + si_list = ns_scope2.Find(names[i]); + if (si_list != null && si_list.FirstOrDefault().sym_info is common_namespace_node) + ns_scope2 = (si_list.FirstOrDefault().sym_info as common_namespace_node).scope; + else + AddError(new NamespaceNotFound(nun.namespace_name.namespace_name, un.location)); + } + scopes.Add(ns_scope2); + } + else if (si_list == null) + AddError(new NamespaceNotFound(nun.namespace_name.namespace_name, un.location)); + } + } + ns_scope.TopScopeArray = scopes.ToArray(); + } + + //convert type predefinitions + foreach (syntax_namespace_node _syntax_namespace_node in namespaces) + { + var cmn = dict[_syntax_namespace_node]; + var scope = cmn.scope; + context.enter_scope(scope); + foreach (declaration decl in _syntax_namespace_node.defs) + { + if (decl is type_declarations) + { + type_declarations type_decls = decl as type_declarations; + foreach (type_declaration td in type_decls.types_decl) + { + if (td.type_def is class_definition) + { + class_definition cl_def = td.type_def as class_definition; + if (cl_def.body == null) + AddError(get_location(cl_def), "TYPE_PREDEFINITION_NOT_ALLOWED"); + common_type_node ctn = null; + if (td.type_name is template_type_name) + ctn = context.advanced_create_type(td.type_name.name + "`" + (td.type_name as template_type_name).template_args.Count, get_location(td.type_name), (td.type_def as class_definition).keyword == class_keyword.Interface, (cl_def.attribute & SyntaxTree.class_attribute.Partial) == SyntaxTree.class_attribute.Partial, cl_def.attribute); + else + ctn = context.advanced_create_type(td.type_name.name, get_location(td.type_name), (td.type_def as class_definition).keyword == class_keyword.Interface, (cl_def.attribute & SyntaxTree.class_attribute.Partial) == SyntaxTree.class_attribute.Partial, cl_def.attribute); + ctn.ForwardDeclarationOnly = true; + if ((td.type_def as class_definition).keyword == class_keyword.Interface) + ctn.IsInterface = true; + context.converted_type = null; + context.add_type_header(td, ctn); + } + else if (td.type_def is procedure_header || td.type_def is function_header || td.type_def is named_type_reference) + { + + } + else if (td.type_def is enum_type_definition) + { + hard_node_test_and_visit(td); + } + else + AddError(get_location(decl), "NAMESPACE_SHOULD_CONTAINS_ONLY_TYPES"); + } + + } + else if (decl is procedure_definition && get_location(decl) == null) + { + //yield + } + else + AddError(get_location(decl), "NAMESPACE_SHOULD_CONTAINS_ONLY_TYPES"); + } + + context.leave_scope(); + } + + + foreach (syntax_namespace_node _syntax_namespace_node in namespaces) + { + common_namespace_node cmn = dict[_syntax_namespace_node]; + context.enter_scope(cmn.scope); + foreach (declaration decl in _syntax_namespace_node.defs) + { + if (decl is type_declarations) + { + type_declarations type_decls = decl as type_declarations; + foreach (type_declaration td in type_decls.types_decl) + { + if (td.type_def is procedure_header || td.type_def is function_header || td.type_def is named_type_reference) + { + hard_node_test_and_visit(td); + if (!(td.type_def is named_type_reference)) + { + common_type_node ctn = context.converted_namespace.types[context.converted_namespace.types.Count - 1]; + ctn.SetName(_syntax_namespace_node.name + "." + ctn.name); + } + } + } + } + } + context.leave_scope(); + } + foreach (syntax_namespace_node _syntax_namespace_node in namespaces) + { + common_namespace_node cmn = dict[_syntax_namespace_node]; + context.enter_scope(cmn.scope); + foreach (declaration decl in _syntax_namespace_node.defs) + { + if (decl is type_declarations) + { + type_declarations type_decls = decl as type_declarations; + foreach (type_declaration td in type_decls.types_decl) + { + if (td.type_def is class_definition) + { + hard_node_test_and_visit(td); + common_type_node ctn = context.converted_namespace.types[context.converted_namespace.types.Count - 1]; + ctn.SetName(_syntax_namespace_node.name + "." + ctn.name); + } + } + } + + } + context.leave_scope(); + } + foreach (syntax_namespace_node _syntax_namespace_node in namespaces) + { + common_namespace_node cmn = dict[_syntax_namespace_node]; + context.enter_scope(cmn.scope); + foreach (declaration decl in _syntax_namespace_node.defs) + { + if (decl is procedure_definition) + { + hard_node_test_and_visit(decl); + } + } + context.leave_scope(); + } + foreach (syntax_namespace_node _syntax_namespace_node in namespaces) + { + common_namespace_node cmn = dict[_syntax_namespace_node]; + context.enter_scope(cmn.scope); + foreach (declaration decl in _syntax_namespace_node.defs) + { + if (decl is type_declarations) + { + type_declarations type_decls = decl as type_declarations; + foreach (type_declaration td in type_decls.types_decl) + { + if (td.type_def is class_definition) + { + context.converted_type = context.get_type_to_realize(td); + class_definition cl_def = td.type_def as class_definition; + visit_class_member_realizations(cl_def.body); + context.converted_type = null; + } + } + } + } + context.leave_scope(); + } + context.namespace_converted = false; + context.clear_member_bindings(); + + } + + public override void visit(SyntaxTree.compilation_unit _compilation_unit) + { + if (_compilation_unit.source_context == null) + throw new NotSupportedError(); + throw new NotSupportedError(get_location(_compilation_unit)); + } + + public override void visit(SyntaxTree.program_body _program_body) + { + throw new NotSupportedError(get_location(_program_body)); + } + + public override void visit(SyntaxTree.uses_list _uses_list) + { + throw new NotSupportedError(get_location(_uses_list)); + } + + public override void visit(SyntaxTree.uses_unit_in _uses_unit_in) + { + throw new NotSupportedError(get_location(_uses_unit_in)); + } + + public override void visit(SyntaxTree.unit_name _unit_name) + { + throw new NotSupportedError(get_location(_unit_name)); + } + + public override void visit(SyntaxTree.consts_definitions_list _consts_definitions_list) + { + //ssyy + if (context.converting_block() == block_type.type_block && + context.converted_type.IsInterface) + { + AddError(get_location(_consts_definitions_list), "INVALID_INTERFACE_MEMBER"); + } + //\ssyy + foreach (SyntaxTree.const_definition cnst in _consts_definitions_list.const_defs) + cnst.visit(this); + } + + public override void visit(SyntaxTree.const_definition _const_definition) + { + throw new NotSupportedError(get_location(_const_definition)); + } + + private bool IsBoundedArray(type_node tn) + { + return tn.get_internal_interface(internal_interface_kind.bounded_array_interface) != null; + } + + private bool IsUnsizedArray(type_node tn) + { + return tn.get_internal_interface(internal_interface_kind.unsized_array_interface) != null; + } + + private type_node const_def_type=null; + private bool is_typed_const_def=false; + + public override void visit(SyntaxTree.typed_const_definition _typed_const_definition) + { + location cons_loc = get_location(_typed_const_definition.const_value); + constant_definition_node cdn = context.add_const_definition(_typed_const_definition.const_name.name, get_location(_typed_const_definition.const_name)); + type_node tn = convert_strong(_typed_const_definition.const_type); + assign_doc_info(cdn,_typed_const_definition); + check_for_type_allowed(tn,get_location(_typed_const_definition.const_type)); + check_using_static_class(tn, get_location(_typed_const_definition.const_type)); + if (context.converted_type != null && context.converted_func_stack.Empty) + if (!constant_in_class_valid(tn))//proverka na primitivnost konstanty v klasse + AddError(get_location(_typed_const_definition), "CLASS_CONSTANT_CAN_HAVE_ONLY_PRIMITIVE_VALUE"); + if (tn is common_type_node) + { + if (!SemanticRules.DefineMethodsInConstantRecord) + CheckConstantRecordNotBeContainsMethods(tn as common_type_node, get_location(_typed_const_definition.const_type)); + if (!SemanticRules.InheritanceConstantRecord) + //mnozhestvo zdes iskljuchenie + if (tn.base_type is common_type_node && tn.base_type.type_special_kind != SemanticTree.type_special_kind.base_set_type/*tn.base_type != SystemLibrary.SystemLibInitializer.TypedSetType.sym_info as type_node*/) + AddError(get_location(_typed_const_definition.const_type), "CONSTANT_RECORD_CAN_NOT_BE_INHERITANCE"); + } + const_def_type = tn.element_type; + is_typed_const_def = true; + _typed_const_definition.const_value = get_possible_array_const(_typed_const_definition.const_value,tn); + cdn.const_value = convert_strong_to_constant_node(_typed_const_definition.const_value, tn); + const_def_type = null; + is_typed_const_def = false; + if (cdn is class_constant_definition && cdn.constant_value.value == null) + AddError(new NotSupportedError(cons_loc)); + } + + private void CheckConstantRecordNotBeContainsMethods(common_type_node ctn, location loc) + { + if (ctn.is_value) + { + if (ctn.methods.Count > 0) + { + for (int i=0; i 1) + { + AddError(get_location(tpars.idents.idents[1]), "ONLY_ONE_PARAMS_PARAMETER_ALLOWED"); + } + } + + SyntaxTree.array_type arr = tpars.vars_type as SyntaxTree.array_type; + if (tpars.vars_type is SyntaxTree.class_definition || /*tpars.vars_type is SyntaxTree.enum_type_definition ||*/ + (arr != null && arr.indexers != null && arr.indexers.indexers.Count > 0 && arr.indexers.indexers[0] != null)) + { + AddError(get_location(tpars.vars_type), "STRUCT_TYPE_DEFINITION_IN_FORMAL_PARAM"); + } + + type_node tp = convert_strong(tpars.vars_type); + + if (tpars.param_kind == SyntaxTree.parametr_kind.params_parametr) + { + internal_interface ii = tp.get_internal_interface(internal_interface_kind.unsized_array_interface); + if (ii == null) + { + AddError(get_location(tpars.vars_type), "ONLY_UNSIZED_ARRAY_PARAMS_PARAMETER_ALLOWED"); + } + } + foreach (common_parameter ccp in temp_params) + { + ccp.type = tp; + } + + + if (params_met) + { + AddError(get_location(tpars), "ONLY_LAST_PARAMETER_CAN_BE_PARAMS"); + } + if (tpars.param_kind == PascalABCCompiler.SyntaxTree.parametr_kind.params_parametr) + { + params_met = true; + } + } + + } + type_node ret_val_type = null; + if (return_type != null) + { + ret_val_type = convert_strong(return_type); + } + common_type_node del; + if (del_type == null) + { + del = convertion_data_and_alghoritms.type_constructor.create_delegate(type_name, + ret_val_type, parameters, context.converted_namespace, loc); + } + else + { + del = del_type; + convertion_data_and_alghoritms.type_constructor.init_delegate(del, ret_val_type, parameters, loc); + } + context.converted_namespace.types.AddElement(del); + return del; + } + + private string get_template_instance_name(string template_name, System.Collections.Generic.List args) + { + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + sb.Append("$"); + sb.Append("template_"); + sb.Append(template_name); + foreach (string s in args) + { + sb.Append("$"); + sb.Append(s); + } + return sb.ToString(); + } + + private string record_type_name = null; + private bool record_is_generic = false; + + private void check_where_section(SyntaxTree.class_definition cl_def) + { + if (cl_def.where_section != null && cl_def.where_section.defs != null) + { + AddError(get_location(cl_def.where_section), "WHERE_SECTION_ALLOWED_ONLY_IN_GENERICS"); + } + } + + //(ssyy) Проверяет параметры шаблона на совпадение друг с другом + private void check_param_redeclared(List idents) + { + for (int i = 0; i < idents.Count; i++) + for (int j = i + 1; j < idents.Count; j++) + { + if (string.Equals(idents[i].name, idents[j].name, StringComparison.InvariantCultureIgnoreCase)) + { + AddError(get_location(idents[j]), "TEMPLATE_PARAMETER_{0}_REDEFINITION", idents[j].name); + } + } + if (context.top_function != null && context.converted_type != null && context.converted_type.is_generic_type_definition) + { + //List gparams = context.converted_type.generic_params; + foreach (SyntaxTree.ident id in idents) + foreach(SemanticTree.ICommonTypeNode ictn in context.converted_type.generic_params) + if (string.Equals(id.name, ictn.name, StringComparison.InvariantCultureIgnoreCase)) + { + AddError(get_location(id), "TEMPLATE_PARAMETER_{0}_REDEFINITION", id.name); + } + } + } + + private void visit_generic_params(common_type_node ctn, List idents) + { + if (SemanticRules.RuntimeInitVariablesOfGenericParameters) + { + if (SystemLibrary.SystemLibInitializer.RuntimeInitializeFunction != null) // SSM 12/05/15 - из-за отсутствия этого падало при наличии обобщенных классов в системном модуле! Ужас! + SystemLibrary.SystemLibInitializer.RuntimeInitializeFunction.Restore(); + } + ctn.is_generic_type_definition = true; + check_param_redeclared(idents); + ctn.generic_params = new List(); + foreach (SyntaxTree.ident id in idents) + { + common_type_node par = new common_type_node( + id.name, SemanticTree.type_access_level.tal_public, context.converted_namespace, + convertion_data_and_alghoritms.symbol_table.CreateInterfaceScope(null, SystemLibrary.SystemLibrary.object_type.Scope, null), + get_location(id)); + SystemLibrary.SystemLibrary.init_reference_type(par); + par.SetBaseType(SystemLibrary.SystemLibrary.object_type); + par.generic_type_container = ctn; + ctn.generic_params.Add(par); + ctn.scope.AddSymbol(id.name, new SymbolInfo(par)); + if (SemanticRules.RuntimeInitVariablesOfGenericParameters && !ctn.IsInterface && !ctn.IsDelegate) + { + class_field cf = new class_field( + compiler_string_consts.generic_param_kind_prefix + id.name, + SystemLibrary.SystemLibrary.byte_type, + ctn, PascalABCCompiler.SemanticTree.polymorphic_state.ps_static, + SemanticTree.field_access_level.fal_public, null); + ctn.fields.AddElement(cf); + par.runtime_initialization_marker = cf; + } + } + } + + private void visit_generic_params(common_function_node cfn, List idents) + { + check_param_redeclared(idents); + cfn.generic_params = new List(); + foreach (SyntaxTree.ident id in idents) + { + common_type_node par = new common_type_node( + id.name, SemanticTree.type_access_level.tal_public, context.converted_namespace, + convertion_data_and_alghoritms.symbol_table.CreateInterfaceScope(null, SystemLibrary.SystemLibrary.object_type.Scope, null), + get_location(id)); + // voloshinbogdan 2018.05.21 Fix missing attributes translation for generic parameters + make_attributes_for_declaration(id, par); + SystemLibrary.SystemLibrary.init_reference_type(par); + par.SetBaseType(SystemLibrary.SystemLibrary.object_type); + par.generic_function_container = cfn; + cfn.generic_params.Add(par); + cfn.scope.AddSymbol(id.name, new SymbolInfo(par)); + } + } + + + public override void visit(SyntaxTree.type_declaration _type_declaration) + { + if (_type_declaration.type_name.name.ToLower() == "program") + { + AddError(get_location(_type_declaration), "PROGRAM_NAME_FOR_TYPE_NAME_IS_PROHIBITED"); + } + //bool is_template_synonym = false; + //SyntaxTree.array_type at=_type_declaration.type_def as SyntaxTree.array_type; + + if (_type_declaration.type_def is class_definition cd && cd.keyword == class_keyword.Class && + (cd.attribute & SyntaxTree.class_attribute.Static) == SyntaxTree.class_attribute.Static) + { + var name = _type_declaration.type_name.name.ToLower(); + if(context.types_predefined.Select(tn => tn.name.ToLower()).Contains(name)) + AddError(get_location(_type_declaration), "STATIC_CLASS_CANNOT_HAVE_PREDEFINITION"); // #2266 + } + + + template_class tc = null; + SyntaxTree.template_type_name ttn = _type_declaration.type_name as SyntaxTree.template_type_name; + SyntaxTree.class_definition cl_def = _type_declaration.type_def as SyntaxTree.class_definition; + SyntaxTree.function_header function_header = _type_declaration.type_def as SyntaxTree.function_header; + SyntaxTree.procedure_header procedure_header = _type_declaration.type_def as SyntaxTree.procedure_header; + if (cl_def != null && (cl_def.attribute & SyntaxTree.class_attribute.Partial) == SyntaxTree.class_attribute.Partial && cl_def.keyword != SyntaxTree.class_keyword.Class) + { + AddError(get_location(_type_declaration), "ONLY_CLASS_CAN_BE_PARTIAL"); + } + if (ttn != null && cl_def == null && function_header == null && procedure_header == null) + { + location t_loc = get_location(ttn); + context.check_name_free(ttn.name, t_loc); + tc = new template_class(_type_declaration, ttn.name, + context.converted_namespace, + current_document, using_list); + tc.is_synonym = true; + //Проверяем параметры шаблона на совпадение друг с другом + check_param_redeclared(ttn.template_args.idents); + context.AddTemplate(ttn.name, tc, t_loc); + + // SSM 23.10.18. Bug fix #1395. Пытаемся проверить, что это - enum. Повторяем с изменениями код в enum_type_node + if (_type_declaration.type_def is enum_type_definition etd) + { + // значит это возможно enum + //var etd = + foreach (SyntaxTree.enumerator en in etd.enumerators.enumerators) + { + if (!((en.name is named_type_reference) && (en.name as named_type_reference).names.Count() == 1)) + { + // Это tupletype + return; + } + // Все - идентификаторы. Проверяем дальше + SyntaxTree.ident id = (en.name as named_type_reference).FirstIdent; + + // Если равен какому-то имени в параметрах обобщения, то это тип - пропускаем. Ищем не тип или неизвестное имя + if (ttn.template_args.idents.Select(ide => ide.name.ToLower()).Any(s => s.Equals(id.name.ToLower()))) + continue; + var si = context.CurrentScope.Find(id.name); + if ((si == null) || !(si.FirstOrDefault().sym_info is type_node)) + { + // Это точно enum. Выдавать ошибку - enumы не могут быть обобщёнными + AddError(get_location(ttn), "ENUMS_CANNOT_BE_GENERIC"); + } + } + } + // Это не enum. Значит, просто выйти. Так было в коде до SSM 23.10.18 + + return; + + //is_template_synonym = true; + //AddError(new TemplateCanBeClassOnly(get_location(ttn))); + } + if ((function_header != null) || (procedure_header != null)) + { + location loc; + if (function_header != null) + loc = get_location(function_header); + else + loc = get_location(procedure_header); + string del_name = _type_declaration.type_name.name; + if (ttn != null) + { + if (context.top_function != null) + { + AddError(loc, "GENERIC_DELEGATE_INNER_FUNCTION"); + } + del_name += compiler_string_consts.generic_params_infix + ttn.template_args.idents.Count; + } + context.check_name_free(del_name, loc); + common_type_node del_type = convertion_data_and_alghoritms.type_constructor.create_delegate_without_init( + del_name, context.converted_namespace, loc); + //(ssyy) Обработка дженериков + common_type_node tmp_converted_type = null; + if (ttn != null) + { + tmp_converted_type = context.converted_type; + context.converted_type = del_type; + visit_generic_params(del_type, ttn.template_args.idents); + } + if (function_header != null) + { + del_type = convert_function_type(function_header, loc, del_name, del_type); + } + else + { + del_type = convert_function_type(procedure_header, loc, del_name, del_type); + } + if (ttn != null) + { + context.converted_type = tmp_converted_type; + } + //blocks.converted_namespace.types.AddElement(del_type); + CheckWaitedRefTypes(del_type); + if (_type_declaration.attributes != null) + { + make_attributes_for_declaration(_type_declaration,del_type); + } + context.converted_namespace.scope.AddSymbol(del_name, new SymbolInfo(del_type)); + return; + } + if (cl_def == null && ttn == null) + { + string name = _type_declaration.type_name.name; + location loc = get_location(_type_declaration.type_name); + context.check_name_free(name, loc); + is_direct_type_decl = true; + type_node tn = convert_strong(_type_declaration.type_def); + assign_doc_info(tn,_type_declaration); + is_direct_type_decl = false; + if (_type_declaration.type_def is SyntaxTree.named_type_reference|| + _type_declaration.type_def is SyntaxTree.ref_type || _type_declaration.type_def is SyntaxTree.string_num_definition || + _type_declaration.type_def is SyntaxTree.sequence_type || //SSM 01.11.2018 + tn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.array_kind)// || + /*tn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.set_type*/ + { + if (context.converted_func_stack.Empty) + { + type_synonym ts = new type_synonym(name, tn, loc); + assign_doc_info(ts,_type_declaration); + context.converted_namespace.type_synonyms.Add(ts); + } + } + else + { + tn.SetName(context.BuildName(name)); + } + if (_type_declaration.attributes != null) + if (_type_declaration.type_def is SyntaxTree.enum_type_definition) + { + make_attributes_for_declaration(_type_declaration,tn); + (tn as common_type_node).add_additional_enum_operations(); + } + else + AddError(get_location(_type_declaration.attributes), "ATTRIBUTES_APPLICABLE_ONLY_TO_THESE_TYPES"); + context.add_type(name, tn, loc); + return; + } + //Проверим, что список template-ов не пуст + bool is_generic = false; + if (ttn != null && cl_def != null && cl_def.template_args == null) + { + cl_def.template_args = ttn.template_args; + } + if (cl_def != null && cl_def.template_args != null && cl_def.template_args.idents != null && + cl_def.template_args.idents.Count > 0) + { + switch (cl_def.keyword) + { + case PascalABCCompiler.SyntaxTree.class_keyword.TemplateClass: + cl_def.keyword = PascalABCCompiler.SyntaxTree.class_keyword.Class; + is_generic = false; + check_where_section(cl_def); + break; + case PascalABCCompiler.SyntaxTree.class_keyword.TemplateRecord: + cl_def.keyword = PascalABCCompiler.SyntaxTree.class_keyword.Record; + is_generic = false; + check_where_section(cl_def); + break; + case PascalABCCompiler.SyntaxTree.class_keyword.TemplateInterface: + cl_def.keyword = PascalABCCompiler.SyntaxTree.class_keyword.Interface; + is_generic = false; + check_where_section(cl_def); + break; + default: + is_generic = true; + break; + } + + if (!is_generic) + { + string t_name = _type_declaration.type_name.name; + location t_loc = get_location(_type_declaration.type_name); + List sil = context.find_only_in_namespace(t_name); + + tc = null; + //Ищем предописание + if (sil != null) + { + tc = sil.FirstOrDefault().sym_info as template_class; + if (tc == null || !tc.ForwardDeclarationOnly) + { + AddError(new NameRedefinition(t_name, convertion_data_and_alghoritms.get_location(sil.FirstOrDefault().sym_info), t_loc)); + } + SyntaxTree.class_definition prev_cl_def = tc.type_dec.type_def as SyntaxTree.class_definition; + if (prev_cl_def.keyword != cl_def.keyword || prev_cl_def.template_args.idents.Count != cl_def.template_args.idents.Count) + { + AddError(t_loc, "FORWARD_TEMPLATE_{0}_DECLARATION_MISMATCH_DECLARATION", t_name); + } + for (int k = 0; k < cl_def.template_args.idents.Count; k++) + { + if (string.Compare(cl_def.template_args.idents[k].name, prev_cl_def.template_args.idents[k].name, true) != 0) + { + AddError(t_loc, "FORWARD_TEMPLATE_{0}_DECLARATION_MISMATCH_DECLARATION", t_name); + } + } + if (cl_def.body == null) + { + AddError(new NameRedefinition(t_name, convertion_data_and_alghoritms.get_location(sil.FirstOrDefault().sym_info), t_loc)); + } + tc.type_dec = _type_declaration; + tc.ForwardDeclarationOnly = false; + return; + } + + tc = new template_class(_type_declaration, t_name, + context.converted_namespace, + current_document, using_list); + + //Проверяем параметры шаблона на совпадение друг с другом + check_param_redeclared(cl_def.template_args.idents); + + tc.ForwardDeclarationOnly = cl_def.body == null; + context.AddTemplate(t_name, tc, t_loc); + if (!tc.ForwardDeclarationOnly && template_class.check_template_definitions) + { + int count = cl_def.template_args.idents.Count; + List test_types = new List(count); + for (int i = 0; i < count; i++) + { + test_types.Add(new indefinite_type_node(cl_def.template_args.idents[i].name)); + } + instance(tc, test_types, t_loc); + } + return; + } + } + //(ssyy) Теперь проверим на модификатор template + if (cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.TemplateClass || + cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.TemplateRecord || + cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.TemplateInterface) + { + //Ошибка, т.к. нет списка шаблонных параметров. + AddError(get_location(_type_declaration.type_name), "TEMPLATE_PARAMS_EXPECTED"); + } + bool predefined_generic = false; + if (is_generic) + { + List sil = context.find_only_in_namespace(_type_declaration.type_name.name + compiler_string_consts.generic_params_infix + + cl_def.template_args.idents.Count.ToString()); + if (!(sil != null && sil.FirstOrDefault().sym_info is common_type_node && ((sil.FirstOrDefault().sym_info as common_type_node).IsPartial || context.types_predefined.IndexOf(sil.FirstOrDefault().sym_info as common_type_node) != -1))) + { + context.check_name_free(_type_declaration.type_name.name, get_location(_type_declaration.type_name)); + } + else + predefined_generic = true; + _type_declaration.type_name.name += compiler_string_consts.generic_params_infix + + cl_def.template_args.idents.Count.ToString(); + } + if (cl_def.keyword == SyntaxTree.class_keyword.Record) + { + string name = record_type_name = _type_declaration.type_name.name; + if (context.top_function != null && context.top_function.generic_params != null) + { + AddError(get_location(_type_declaration.type_name), "NESTED_RECORDS_IN_GENERIC_FUNCTIONS_NOT_ALLOWED"); + } + record_is_generic = is_generic; + location loc = get_location(_type_declaration.type_name); + context.check_name_free(name, loc); + //context.create_record_type(loc, record_type_name); + is_direct_type_decl = true; + type_node tn = convert_strong(_type_declaration.type_def); + assign_doc_info(tn,_type_declaration); + if (_type_declaration.attributes != null) + { + make_attributes_for_declaration(_type_declaration, tn); + } + is_direct_type_decl = false; + record_type_name = null; + record_is_generic = false; + tn.SetName(context.BuildName(name)); + return; + } + + //(ssyy) Флаг показывает, создаём ли мы интерфейс + bool interface_creating = (cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.Interface); + + common_type_node ctn = context.advanced_create_type(_type_declaration.type_name.name, get_location(_type_declaration.type_name), interface_creating, (cl_def.attribute & SyntaxTree.class_attribute.Partial) == SyntaxTree.class_attribute.Partial, cl_def.attribute); + assign_doc_info(ctn,_type_declaration); + if (_type_declaration.attributes != null) + { + make_attributes_for_declaration(_type_declaration, ctn); + } + if (cl_def.keyword == class_keyword.Class || cl_def.keyword == class_keyword.Interface) + ctn.is_class = true;//nado ranshe pomechat kak is_class + if (is_generic) + { + if (predefined_generic) + { + if (ctn.generic_params.Count != cl_def.template_args.idents.Count) + AddError(get_location(cl_def.template_args), "GENERIC_PARAMETERS_MISMATCH"); + foreach (ident id in cl_def.template_args.idents) + { + SymbolInfo si = ctn.find_first_in_type(id.name); + if (si == null) + AddError(get_location(cl_def.template_args), "GENERIC_PARAMETERS_MISMATCH"); + if (!(si.sym_info is common_type_node && (si.sym_info as common_type_node).is_generic_parameter)) + AddError(get_location(cl_def.template_args), "GENERIC_PARAMETERS_MISMATCH"); + } + } + else + { + context.create_generic_indicator(ctn); + visit_generic_params(ctn, cl_def.template_args.idents); + } + } + if (predefined_generic && cl_def.where_section != null && cl_def.where_section.defs.Count > 0) + AddError(get_location(cl_def.where_section), "WHERE_SECTION_NOT_ALLOWED"); + if ((cl_def.attribute & SyntaxTree.class_attribute.Partial) == SyntaxTree.class_attribute.Partial && cl_def.class_parents != null) + { + type_node tn = ret.visit(cl_def.class_parents.types[0]); + if (!tn.IsInterface && ctn.base_type != SemanticRules.ClassBaseType && ctn.base_type != null && !ctn.base_type.IsInterface && tn != ctn.base_type) + AddError(get_location(cl_def.class_parents), "PARTIAL_CLASS_PARENTS_MISMATCH"); + /*if (ctn.ImplementingInterfaces.Count != cl_def.class_parents.types.Count - 1) + AddError(get_location(cl_def.class_parents), "PARTIAL_CLASS_PARENTS_MISMATCH"); + for (int i=1; i < cl_def.class_parents.types.Count; i++) + { + tn = ret.visit(cl_def.class_parents.types[i]); + if (ctn.ImplementingInterfaces[i-1] != tn) + AddError(get_location(cl_def.class_parents.types[i]), "PARTIAL_CLASS_PARENTS_MISMATCH"); + }*/ + } + + visit_where_list(cl_def.where_section); + + CheckWaitedRefTypes(ctn); + is_direct_type_decl = true; + hard_node_test_and_visit(_type_declaration.type_def); + check_where_from_base_class(ctn); + // frninja 28/04/16 - режем мусорные методы хелперы yield + { + var toRemove = ctn.methods.Where(m => m.is_yield_helper).ToArray(); + foreach (var m in toRemove) + { + ctn.methods.remove(m); + } + } + // end frninja + + is_direct_type_decl = false; + } + + private bool attribute_converted = false; + private AttributeTargets get_usage_attrs(type_node tn, out bool allowMultiple) + { + allowMultiple = false; + if (tn is common_type_node) + { + common_type_node ctn = tn as common_type_node; + for (int i=0; i cnst_list = new List(); + foreach (expression_node ex in (en as array_initializer).element_values) + { + constant_node elem_cn = convert_strong_to_constant_node(ex, ex.type); + check_for_strong_constant(elem_cn, ex.location); + cnst_list.Add(elem_cn); + } + + cn = convert_strong_to_constant_node(new array_const(cnst_list, en.location), en.type); + } + else + { + cn = convert_strong_to_constant_node(en, en.type); + check_for_strong_constant(cn, en.location); + } + + attr_node.args.Add(cn); + } + if (attr.arguments != null) + { + for (int i = cnstr_args.expressions.Count; i < attr.arguments.expressions.Count; i++) + { + SyntaxTree.expression e = attr.arguments.expressions[i]; + if (!(e is SyntaxTree.bin_expr && (e as SyntaxTree.bin_expr).operation_type == SyntaxTree.Operators.Equal + && (e as SyntaxTree.bin_expr).left is SyntaxTree.ident)) + { + AddError(get_location(e), "EXPECTED_ATTRIBUTE_INITIALIZER"); + } + else + { + SyntaxTree.ident id = (e as SyntaxTree.bin_expr).left as SyntaxTree.ident; + SymbolInfo si = tn.find_first_in_type(id.name); + definition_node dn; + if (si != null) + dn = context.check_name_node_type(id.name, si, get_location(id), general_node_type.property_node, general_node_type.variable_node); + else + dn = context.check_name_node_type(id.name, null, get_location(id), general_node_type.property_node, general_node_type.variable_node); + type_node mem_tn = null; + if (dn is property_node) + { + property_node pn = dn as property_node; + attr_node.prop_names.Add(pn); + if (pn.set_function == null) + AddError(new ThisPropertyCanNotBeWrited(pn, get_location(id))); + if (pn.set_function.parameters.Count != 1) + AddError(get_location(id), "INDEX_PROPERTY_INITIALIZING_NOT_VALID"); + mem_tn = pn.set_function.parameters[0].type; + } + else if (dn is var_definition_node) + { + attr_node.field_names.Add(dn as var_definition_node); + mem_tn = (dn as var_definition_node).type; + } + else + { + throw new CompilerInternalError("Bad general node type for attribute initializer"); + } + //SyntaxTree.assign tmp_ass = new SyntaxTree.assign(id,(e as SyntaxTree.bin_expr).right,SyntaxTree.Operators.Assignment); + //tmp_ass.source_context = e.source_context; + //basic_function_call tmp_bfc = convert_strong(tmp_ass) as basic_function_call; + constant_node cn = convert_strong_to_constant_node((e as SyntaxTree.bin_expr).right, mem_tn); + check_for_strong_constant(cn, get_location((e as SyntaxTree.bin_expr).right)); + if (dn is property_node) + attr_node.prop_initializers.Add(cn); + else + attr_node.field_initializers.Add(cn); + } + } + } + attr_node.qualifier = qualifier; + ctn.attributes.AddElement(attr_node); + } + } + } + + private void make_attributes_for_declaration(SyntaxTree.unit_module un, common_unit_node cun) + { + if (cun.attributes != null) + { + Hashtable ht = new Hashtable(); + foreach (SyntaxTree.simple_attribute_list sal in un.attributes.attributes) + for (int j = 0; j < sal.attributes.Count; j++) + { + SyntaxTree.attribute attr = sal.attributes[j]; + attribute_converted = true; + type_node tn = convert_strong(attr.type); + bool is_attr = false; + type_node tmp = tn; + while (tmp.base_type != null && !is_attr) + { + is_attr = tmp.base_type == SystemLibrary.SystemLibrary.attribute_type; + tmp = tmp.base_type; + } + if (!is_attr) + AddError(get_location(attr), "CLASS_{0}_NOT_ATTRIBUTE", tn.name); + bool allowMultiple = false; + AttributeTargets targets = get_usage_attrs(tn, out allowMultiple); + if (ht.Contains(tn) && !allowMultiple) + { + AddError(get_location(attr), "DUPLICATE_ATTRIBUTE_{0}_APPLICATION", tn.name); + } + else + ht[tn] = tn; + SemanticTree.attribute_qualifier_kind qualifier = SemanticTree.attribute_qualifier_kind.none_kind; + if (attr.qualifier != null) + if (j == 0) + { + if (string.Compare(attr.qualifier.name, "return", true) == 0) + { + if (context.top_function == null) + AddError(get_location(attr), "ATTRIBUTE_APPLICABLE_ONLY_TO_METHOD"); + if (context.top_function.return_value_type == null || context.top_function.return_value_type == SystemLibrary.SystemLibrary.void_type) + AddError(get_location(attr), "EXPECTED_RETURN_VALUE_FOR_ATTRIBUTE"); + throw new NotSupportedError(get_location(attr.qualifier)); + qualifier = SemanticTree.attribute_qualifier_kind.return_kind; + } + else + throw new NotSupportedError(get_location(attr.qualifier)); + } + else + AddError(get_location(attr.qualifier), "ATTRIBUTE_QUALIFIER_MUST_BE_FIRST"); + check_for_usage_attribute(cun, targets, tn.name, get_location(attr), qualifier); + + attribute_converted = false; + SyntaxTree.expression_list cnstr_args = new SyntaxTree.expression_list(); + if (attr.arguments != null) + { + foreach (SyntaxTree.expression e in attr.arguments.expressions) + { + if (e is SyntaxTree.bin_expr && (e as SyntaxTree.bin_expr).operation_type == SyntaxTree.Operators.Equal + && (e as SyntaxTree.bin_expr).left is SyntaxTree.ident) + { + break; + } + else + { + cnstr_args.expressions.Add(e); + } + } + } + expressions_list args = new expressions_list(); + for (int i = 0; i < cnstr_args.expressions.Count; i++) + { + constant_node cn = convert_strong_to_constant_node(cnstr_args.expressions[i]); + check_for_strong_constant(cn, get_location(cnstr_args.expressions[i])); + args.AddElement(cn); + } + + base_function_call bfc = create_constructor_call(tn, args, get_location(attr)); + attribute_node attr_node = new attribute_node(bfc.simple_function_node, tn, get_location(un)); + foreach (expression_node en in bfc.parameters) + { + constant_node cn = convert_strong_to_constant_node(en, en.type); + check_for_strong_constant(cn, en.location); + attr_node.args.Add(cn); + } + if (attr.arguments != null) + { + for (int i = cnstr_args.expressions.Count; i < attr.arguments.expressions.Count; i++) + { + SyntaxTree.expression e = attr.arguments.expressions[i]; + if (!(e is SyntaxTree.bin_expr && (e as SyntaxTree.bin_expr).operation_type == SyntaxTree.Operators.Equal + && (e as SyntaxTree.bin_expr).left is SyntaxTree.ident)) + { + AddError(get_location(e), "EXPECTED_ATTRIBUTE_INITIALIZER"); + } + else + { + SyntaxTree.ident id = (e as SyntaxTree.bin_expr).left as SyntaxTree.ident; + List sil = tn.find(id.name); + definition_node dn; + if(sil != null) + dn = context.check_name_node_type(id.name, sil?.FirstOrDefault(), get_location(id), general_node_type.property_node, general_node_type.variable_node); + else + dn = context.check_name_node_type(id.name, null, get_location(id), general_node_type.property_node, general_node_type.variable_node); + type_node mem_tn = null; + if (dn is property_node) + { + property_node pn = dn as property_node; + attr_node.prop_names.Add(pn); + if (pn.set_function == null) + AddError(new ThisPropertyCanNotBeWrited(pn, get_location(id))); + if (pn.set_function.parameters.Count != 1) + AddError(get_location(id), "INDEX_PROPERTY_INITIALIZING_NOT_VALID"); + mem_tn = pn.set_function.parameters[0].type; + } + else if (dn is var_definition_node) + { + attr_node.field_names.Add(dn as var_definition_node); + mem_tn = (dn as var_definition_node).type; + } + else + { + throw new CompilerInternalError("Bad general node type for attribute initializer"); + } + constant_node cn = convert_strong_to_constant_node((e as SyntaxTree.bin_expr).right, mem_tn); + check_for_strong_constant(cn, get_location((e as SyntaxTree.bin_expr).right)); + if (dn is property_node) + attr_node.prop_initializers.Add(cn); + else + attr_node.field_initializers.Add(cn); + } + } + } + attr_node.qualifier = qualifier; + cun.attributes.AddElement(attr_node); + if (cun.namespaces.Count > 0) + cun.namespaces[0].attributes.AddElement(attr_node); + } + } + } + + private void check_for_strong_constant(constant_node cn, location loc) + { + switch (cn.semantic_node_type) + { + case semantic_node_type.bool_const_node : + case semantic_node_type.byte_const_node : + case semantic_node_type.char_const_node : + case semantic_node_type.sbyte_const_node : + case semantic_node_type.short_const_node : + case semantic_node_type.ushort_const_node : + case semantic_node_type.int_const_node : + case semantic_node_type.uint_const_node : + case semantic_node_type.long_const_node : + case semantic_node_type.ulong_const_node : + case semantic_node_type.float_const_node : + case semantic_node_type.double_const_node : + case semantic_node_type.string_const_node : + case semantic_node_type.enum_const : + case semantic_node_type.null_const_node : + return; + default: + AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); + break; + } + } + + internal void check_using_static_class(type_node tn, location loc) + { + if (tn.IsStatic) + AddError(loc, "USING_STATIC_CLASS_NOT_VALID"); + } + + internal void check_for_type_allowed(type_node tn, location loc) + { + if (tn == SystemLibrary.SystemLibrary.void_type) + AddError(loc, "TYPE_{0}_NOT_VALID", tn.name); + } + + private void check_cycle_inheritance(common_type_node cnode, type_node base_of_cnode) + { + List base_params = new List(); + base_params.Add(cnode); + common_type_node bt = base_of_cnode as common_type_node; + while (bt != null && bt.is_generic_parameter) + { + if (base_params.Contains(bt)) + { + AddError(bt.loc, "TYPE_{0}_DERIVED_FROM_ITSELF", bt.name); + } + base_params.Add(bt); + bt = bt.base_type as common_type_node; + } + } + + private void check_cycle_interface_inheritance(common_type_node cnode, type_node base_of_cnode, List interfaces) + { + // Для интерфейсов всё это излишне. Поскольку нельзя использовать предописанные интерфейсы в списке наследования, то + // циклически интерфейс может наследовать только от себя. Поэтому достаточно проверять нерекурсивно свой список ImplementingInterfaces и если там есть этот интерфейс, то ошибка + if (!cnode.IsInterface) + return; + interfaces.Add(cnode); + common_type_node bt = base_of_cnode as common_type_node; + if (bt != null && bt.original_generic != null) + bt = bt.original_generic as common_type_node; + if (bt != null) + { + if (interfaces.Contains(bt)) + { + AddError(bt.loc, "TYPE_{0}_DERIVED_FROM_ITSELF", bt.PrintableName); + } + interfaces.Add(bt); + foreach (var tn in bt.ImplementingInterfaces) + { + check_cycle_interface_inheritance(bt, tn as type_node, interfaces); + } + } + } + + private void check_where_from_base_class(common_type_node ctn) + { + if (ctn.base_type != null && ctn.base_type.is_generic_type_instance && ctn.is_generic_type_definition) + { + common_type_node bctn = ctn.base_type.original_generic as common_type_node; + compiled_type_node bctn2 = ctn.base_type.original_generic as compiled_type_node; + Dictionary where_cache = new Dictionary(); + foreach (SemanticTree.ICommonTypeNode t in ctn.generic_params) + { + int ind = ctn.base_type.instance_params.IndexOf(t as type_node); + if (ind != -1) + { + if (bctn != null) + where_cache.Add(bctn.generic_params[ind].name, t); + else + where_cache.Add(bctn2.generic_params[ind].name, t); + } + + } + if (bctn != null && bctn.generic_params != null) + { + foreach (SemanticTree.ICommonTypeNode t in bctn.generic_params) + { + SemanticTree.ICommonTypeNode thist = null; + where_cache.TryGetValue(t.name, out thist); + if (thist == null) + continue; + if (t.is_class || t.is_value_type || t.methods.Length > 0 || t.base_type != SystemLibrary.SystemLibrary.object_type) + { + + //if (thist.is_class != t.is_class || thist.is_value_type != t.is_value_type /*&& !(t.is_value_type && thist.base_type.is_value_type)*/ // последнее непонятно + // || thist.methods.Length != t.methods.Length || // это наличие конструктора + // t.base_type != thist.base_type && !type_table.is_derived(t.base_type as type_node, thist.base_type as type_node)) + if (t.is_class && !thist.is_class) + AddError(ctn.loc, "WHERE_SPECIFIER_MISMATCH"); + if (t.is_value_type && !thist.is_value_type) + AddError(ctn.loc, "WHERE_SPECIFIER_MISMATCH"); + if (t.methods.Length > thist.methods.Length) + AddError(ctn.loc, "WHERE_SPECIFIER_MISMATCH"); + if (t.base_type != SystemLibrary.SystemLibrary.object_type && !type_table.is_type_or_original_generics_equal(t.base_type as type_node, thist.base_type as type_node)) + AddError(ctn.loc, "WHERE_SPECIFIER_MISMATCH"); + + } + } + } + else if (bctn2 != null && bctn2.generic_params != null) + { + foreach (compiled_type_node t in bctn2.generic_params) + { + SemanticTree.ICommonTypeNode thist = null; + where_cache.TryGetValue(t.name, out thist); + if (thist == null) + continue; + if (t.is_value_type || t.base_type != SystemLibrary.SystemLibrary.object_type) + { + if (thist.is_value_type != t.is_value_type && !(t.is_value_type && thist.base_type.is_value_type) || thist.base_type != t.base_type) + AddError(ctn.loc, "WHERE_SPECIFIER_MISMATCH"); + } + } + } + } + } + + private void visit_where_list(SyntaxTree.where_definition_list where_list) + { + if (where_list == null) + { + return; + } + context.BeginSkipGenericInstanceChecking(); + List gparams = null; + common_function_node cfn = context.top_function; + if (cfn != null) + { + if (!cfn.is_generic_function) + { + AddError(get_location(where_list), "WHERE_SECTION_ALLOWED_ONLY_IN_GENERICS"); + return; + } + gparams = cfn.generic_params; + } + else + { + if (!context.converted_type.is_generic_type_definition) + { + AddError(get_location(where_list), "WHERE_SECTION_ALLOWED_ONLY_IN_GENERICS"); + return; + } + gparams = context.converted_type.generic_params; + } + List used_types = new List(where_list.defs.Count); + foreach (SyntaxTree.where_definition wd in where_list.defs) + { + foreach (SyntaxTree.ident wd_id in wd.names.idents) + { + bool param_not_found = true; + foreach (common_type_node param in gparams) + { + if (String.Equals(param.name, wd_id.name, StringComparison.InvariantCultureIgnoreCase)) + { + //Нашли нужный шаблонный параметр + if (used_types.Contains(param)) + { + AddError(get_location(wd.names), "SPECIFICATORS_FOR_{0}_ALREADY_EXIST", wd_id.name); + } + add_generic_eliminations(param, wd.types.defs); + used_types.Add(param); + param_not_found = false; + break; + } + } + if (param_not_found) + { + AddError(new UndefinedNameReference(wd.names.idents[0].name, get_location(wd.names))); + } + } + } + context.EndSkipGenericInstanceChecking(); + } + + //Добавляет ограничители для параметра шаблона + private void add_generic_eliminations(common_type_node param, List specificators) + { + Hashtable used_interfs = new Hashtable(); + for (int i = 0; i < specificators.Count; ++i) + { + SyntaxTree.declaration_specificator ds = specificators[i] as SyntaxTree.declaration_specificator; + if (ds != null) + { + switch (ds.specificator) + { + case SyntaxTree.DeclarationSpecificator.WhereDefClass: + if (i == 0) + { + param.is_class = true; + } + else + { + AddError(get_location(specificators[i]), "CLASS_OR_RECORD_SPECIFICATOR_MUST_BE_FIRST"); + } + break; + case SyntaxTree.DeclarationSpecificator.WhereDefValueType: + if (i == 0) + { + param.internal_is_value = true; + } + else + { + AddError(get_location(specificators[i]), "CLASS_OR_RECORD_SPECIFICATOR_MUST_BE_FIRST"); + } + break; + case SyntaxTree.DeclarationSpecificator.WhereDefConstructor: + if (i == specificators.Count - 1) + { + generic_parameter_eliminations.add_default_ctor(param); + } + else + { + AddError(get_location(specificators[i]), "CONSTRUCTOR_SPECIFICATOR_MUST_BE_LAST"); + } + break; + } + } + else + { + SyntaxTree.named_type_reference ntr = specificators[i] as SyntaxTree.named_type_reference; + if (ntr == null) + { + AddError(get_location(specificators[i]), "SPECIFICATOR_MUST_BE_TYPE_REFERENCE"); + } + else + { + type_node spec_type = ret.visit(ntr); + if (spec_type is ref_type_node || spec_type == SystemLibrary.SystemLibrary.void_type || spec_type == SystemLibrary.SystemLibrary.pointer_type) + AddError(new SimpleSemanticError(get_location(specificators[i]), "INAVLID_TYPE")); + //if (spec_type.is_class) + // param.is_class = true; + if (spec_type.IsInterface) + { + if (used_interfs[spec_type] != null) + { + AddError(get_location(specificators[i]), "INTERFACE_{0}_ALREADY_ADDED_TO_IMPLEMENTING_LIST", spec_type.PrintableName); + } + else + { + used_interfs.Add(spec_type, spec_type); + } + //Добавляем интерфейс + type_table.AddInterface(param, spec_type, get_location(specificators[i])); + } + else + { + if (i != 0) + { + AddError(get_location(specificators[i]), "PARENT_SPECIFICATOR_MUST_BE_FIRST"); + } + else + { + if (spec_type.is_value) + AddError(get_location(specificators[i]), "RECORD_CAN_NOT_BE_USED_AS_PARENT_SPECIFICATOR"); + //Тип-предок + if (spec_type == SystemLibrary.SystemLibrary.object_type) + { + AddError(get_location(specificators[i]), "OBJECT_CAN_NOT_BE_USED_AS_PARENT_SPECIFICATOR"); + } + /*if (spec_type == SystemLibrary.SystemLibrary.enum_base_type) + { + AddError(get_location(specificators[i]), "ENUM_CAN_NOT_BE_USED_AS_PARENT_SPECIFICATOR"); + }*/ + if (spec_type.IsStatic) + AddError(get_location(specificators[i]), "STATIC_CLASS_CAN_NOT_BE_USED_AS_PARENT_SPECIFICATOR"); + check_cycle_inheritance(param, spec_type); + param.SetBaseType(spec_type); + } + } + } + } + } + InitInterfaceScope(param); + } + + private bool is_direct_type_decl = false; + + private bool FunctionExsistsInSymbolInfo(function_node fn, List sil) + { + if (sil != null) + { + foreach (SymbolInfo si in sil) + { + if (si.sym_info is function_node) + if (convertion_data_and_alghoritms.function_eq_params(fn, si.sym_info as function_node)) + return true; + } + } + return false; + } + + internal bool body_exists; + + internal bool current_converted_method_not_in_class_defined = false; + internal bool assign_is_converting = false; + + //lroman// + public void visit_lambda_header(SyntaxTree.function_header _function_header, SyntaxTree.proc_block proc_body) + { + hard_node_test_and_visit(_function_header.name); + if (context.converted_template_type != null) + { + return; + } + if (_function_header.template_args != null) + { + visit_generic_params(context.top_function, _function_header.template_args.idents); + } + SymbolInfo si = context.create_special_names(); + weak_node_test_and_visit(_function_header.parameters); + type_node tn = null; + + #region Вывод типа возвращаемого значения лямбды + + //lroman// + if (LambdaHelper.IsLambdaName(_function_header.name.meth_name)) + { + if (_function_header.return_type != null && _function_header.return_type is SyntaxTree.lambda_inferred_type) + LambdaHelper.InferResultType(_function_header, proc_body, this); + } + //\lroman// + + #endregion + + if (_function_header.return_type == null) + { + if (context.top_function.IsOperator) + AddError(get_location(_function_header), "FUNCTION_NEED_RETURN_TYPE"); + } + if (_function_header.return_type != null) + { + check_parameter_on_complex_type(_function_header.return_type); + tn = convert_strong(_function_header.return_type); + //if (tn == SystemLibrary.SystemLibrary.void_type) + // AddError(new VoidNotValid(get_location(_function_header.return_type))); + check_for_type_allowed(tn,get_location(_function_header.return_type)); + check_using_static_class(tn, get_location(_function_header.return_type)); + } + //(ssyy) moved up, так как при проверке аттрибута override надо знать тип возвращаемого значения + context.top_function.return_value_type = tn; + assign_doc_info(context.top_function,_function_header); + if (_function_header.attributes != null) + { + make_attributes_for_declaration(_function_header, context.top_function); + } + if (context.converted_type != null && has_dll_import_attribute(context.top_function)) + AddError(get_dll_import_attribute(context.top_function).location, "DLLIMPORT_ATTRIBUTE_CANNOT_BE_APPLIED_TO_METHOD"); + if (_function_header.name.class_name != null) + with_class_name = true; + if (_function_header.class_keyword && !has_static_attr(_function_header.proc_attributes.proc_attributes)) + { + SyntaxTree.procedure_attribute pa = new SyntaxTree.procedure_attribute(PascalABCCompiler.SyntaxTree.proc_attribute.attr_static); + pa.source_context = _function_header.source_context; + _function_header.proc_attributes.proc_attributes.Add(pa); + } + weak_node_test_and_visit(_function_header.proc_attributes); + if (context.top_function.IsOperator) + { + common_method_node cmmn = context.top_function as common_method_node; + //if (cmmn == null) + //{ + // throw new OverloadOperatorMustBeStaticFunction(get_location(_function_header), context.top_function); + //} + if (cmmn != null && cmmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + { + AddError(get_location(_function_header), "OVERLOADED_OPERATOR_MUST_BE_STATIC_FUNCTION"); + } + if (cmmn != null && (cmmn.name == compiler_string_consts.implicit_operator_name || cmmn.name == compiler_string_consts.explicit_operator_name)) + if (!convertion_data_and_alghoritms.eq_type_nodes(tn, cmmn.comperehensive_type as type_node) && !convertion_data_and_alghoritms.eq_type_nodes(cmmn.comperehensive_type as type_node, cmmn.parameters[0].type)) + { + AddError(get_location(_function_header.return_type), "RETURN_VALUE_SHOULD_HAVE_TYPE_{0}", (cmmn.comperehensive_type as type_node).PrintableName); + } + else if (convertion_data_and_alghoritms.eq_type_nodes(tn,cmmn.parameters[0].type)) + { + AddError(get_location(_function_header), "CIRCURAL_TYPE_CONVERSION_DEFINITION"); + } + } + with_class_name = false; + if (context.top_function != null && context.top_function is common_namespace_function_node && (context.top_function as common_namespace_function_node).ConnectedToType != null && !context.top_function.IsOperator) + { + concrete_parameter_type cpt = concrete_parameter_type.cpt_none; + SemanticTree.parameter_type pt = PascalABCCompiler.SemanticTree.parameter_type.value; + if ((context.top_function as common_namespace_function_node).ConnectedToType.is_value_type) + { + cpt = concrete_parameter_type.cpt_var; + pt = PascalABCCompiler.SemanticTree.parameter_type.var; + } + if (!has_extensionmethod_attr(_function_header.proc_attributes.proc_attributes)) + { + common_parameter cp = new common_parameter(compiler_string_consts.self_word, (context.top_function as common_namespace_function_node).ConnectedToType, pt, + context.top_function, cpt, null, null); + context.top_function.parameters.AddElementFirst(cp); + context.top_function.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(cp)); + } + } + CheckOverrideOrReintroduceExpectedWarning(get_location(_function_header)); + + bool unique = context.close_function_params(body_exists); + if (context.top_function.return_value_type == null) + AddError(get_location(_function_header), "FUNCTION_NEED_RETURN_TYPE"); + if (_function_header.where_defs != null) + { + if (unique) + { + visit_where_list(_function_header.where_defs); + } + else + { + AddError(get_location(_function_header.where_defs), "WHERE_SECTION_MUST_BE_ONLY_IN_FIRST_DECLARATION"); + } + } + convertion_data_and_alghoritms.create_function_return_variable(context.top_function, si); + + //TODO: Разобрать подробнее. + if (!body_exists) + { + if ((context.top_function.semantic_node_type == semantic_node_type.common_method_node) + || ((context.func_stack_size_is_one()) && (_is_interface_part))) + { + //context.leave_block(); + } + } + body_exists = false; + } + //\lroman// + + public override void visit(SyntaxTree.procedure_definition _procedure_definition) + { + // SSM 20.07.13 если это - узел с коротким определением функции без типа возвращаемого значения, то вывести этот тип + var fh = (_procedure_definition.proc_header as SyntaxTree.function_header); + if (fh != null && fh.return_type == null) + { + var bl = _procedure_definition.proc_body as SyntaxTree.block; + if (bl != null && bl.program_code != null) + { + if (bl.program_code.subnodes.Count != 1) + AddError(get_location(fh.name), "ONLY_IN_SHORT_FUNC_DEFS_RETURN_TYPE_CANBE_OMITTED"); + + var ass = bl.program_code.subnodes[0] as SyntaxTree.assign; + if (ass != null && ass.to is ident && (ass.to as ident).name.ToLower()=="result") + { + if (ass.from is nil_const) + AddError(get_location(ass.from), "CAN_NOT_DEDUCE_TYPE_{0}","nil"); + + // undefined_type означает, что где-то в будущем это надо исправить. Потому что и Result будет этого типа + var typ = new semantic_type_node(new undefined_type("#Und",null));//SyntaxTreeBuilder.BuildSameType(ass.from); + fh.return_type = typ; + } + else AddError(get_location(fh.name), "ONLY_IN_SHORT_FUNC_DEFS_RETURN_TYPE_CANBE_OMITTED"); + } + } + //\ SSM + + var proc_name = _procedure_definition.proc_header != null && _procedure_definition.proc_header.name != null + ? _procedure_definition.proc_header.name.meth_name + : null; + if (_procedure_definition.proc_header.attributes != null && context.converted_func_stack.size >= 1) + AddError(get_location(_procedure_definition.proc_header), "ATTRIBUTES_FOR_NESTED_FUNCTIONS_NOT_ALLOWED"); + if (context.top_function != null && context.top_function.generic_params != null && !LambdaHelper.IsLambdaName(proc_name) && !(_procedure_definition.proc_header is SyntaxTree.constructor)) + AddError(get_location(_procedure_definition.proc_header), "NESTED_FUNCTIONS_IN_GENERIC_FUNCTIONS_NOT_ALLOWED"); + if (context.top_function != null && _procedure_definition.proc_header.template_args != null && !LambdaHelper.IsLambdaName(proc_name)) + AddError(get_location(_procedure_definition.proc_header), "GENERIC_NESTED_FUNCTIONS_NOT_ALLOWED"); + if (_procedure_definition.proc_header.name != null) + current_converted_method_not_in_class_defined = _procedure_definition.proc_header.name.class_name != null; + else + { + if (_procedure_definition.proc_header is SyntaxTree.constructor) + { + current_converted_method_not_in_class_defined = false; + } + } + bool must_visit_body = true; + if (SemanticRules.OrderIndependedMethodNames && !disable_order_independ && context.converting_block() == block_type.type_block && _procedure_definition.proc_body != null) + { + if (_procedure_definition.proc_header.name != null) + { + if (_procedure_definition.proc_header.name.class_name == null || _procedure_definition.Parent is class_members) // SSM #2173 01/07/20 - добавка после || - озн, что это явное расширение интерфейса + { + must_visit_body = false; + context.is_order_independed_method_description = true; + } + } + else + { + must_visit_body = false; + context.is_order_independed_method_description = true; + } + } + if (SemanticRules.OrderIndependedFunctionNames && !disable_order_independ && context.converting_block() == block_type.namespace_block && _procedure_definition.proc_body != null && _procedure_definition.proc_header.name.class_name == null) + { + if (_procedure_definition.proc_header.name != null) + { + if (_procedure_definition.proc_header.name.class_name == null) + { + must_visit_body = false; + context.is_order_independed_method_description = true; + } + } + else + { + must_visit_body = false; + context.is_order_independed_method_description = true; + } + } + //ssyy + if (context.converting_block() == block_type.type_block && + context.converted_type.IsInterface) + { + AddError(get_location(_procedure_definition), "INVALID_INTERFACE_MEMBER"); + } + //\ssyy + + //ssyy добавил + if (context.converting_block() == block_type.function_block) + { + common_method_node cmnode = context.top_function as common_method_node; + if (cmnode != null && cmnode.is_constructor) + { + //throw new NotSupportedError(get_location(_procedure_definition)); + } + } + //\ssyy + if (context.converted_type != null && context.converted_type.IsStatic && !_procedure_definition.proc_header.class_keyword) + AddError(get_location(_procedure_definition), "STATIC_CLASSES_CANNOT_NON_STATIC_MEMBERS"); + if (_procedure_definition.proc_body == null) + { + body_exists = false; + } + else + { + body_exists = true; + } + + //lroman// + if (_procedure_definition != null && + _procedure_definition.proc_header != null && + _procedure_definition.proc_header is SyntaxTree.function_header && + _procedure_definition.proc_header.name != null && + _procedure_definition.proc_header.name.meth_name != null && + LambdaHelper.IsLambdaName(_procedure_definition.proc_header.name.meth_name)) + { + //!!!!!!!!!!!!!!!!!! + convertion_data_and_alghoritms.check_node_parser_error(_procedure_definition.proc_header); + visit_lambda_header(_procedure_definition.proc_header as SyntaxTree.function_header, _procedure_definition.proc_body); + } + else + { + hard_node_test_and_visit(_procedure_definition.proc_header); + } + //\lroman// + + + // Patterns + + if (context.top_function != null && + context.top_function is common_namespace_function_node commonNode && + commonNode.name.ToLower() == compiler_string_consts.deconstruct_method_name) + { + var deconstructor = commonNode; + + if (!deconstructor.is_extension_method) + { + //AddWarning(); + } + else + { + if (deconstructor.is_generic_function && + deconstructor.generic_parameters_count != GenericParameterIndices(GetSelfParameter(deconstructor).type).Count()) + AddError(get_location(_procedure_definition), "DECONSTRUCTOR_GENERIC_PARAMETERS_SHOULD_BE_DEFINED_BY_SELF_PARAMETER"); + + ExecuteCommonChecks(deconstructor); + } + } + + if (context.top_function != null && + context.top_function is common_method_node methodNode && + methodNode.name.ToLower() == compiler_string_consts.deconstruct_method_name) + { + var deconstructor = methodNode; + + if (deconstructor.is_generic_function) + AddError(get_location(_procedure_definition), "INSTANCE_DECONSTRUCTORS_CANNOT_BE_GENERIC"); + + ExecuteCommonChecks(deconstructor); + } + + // !Patterns + + //ssyy + if (context.converted_template_type != null) + { + if ((context.converted_template_type.type_dec.type_def as SyntaxTree.class_definition).keyword == PascalABCCompiler.SyntaxTree.class_keyword.Interface) + { + AddError(new InterfaceFunctionWithBody(get_location(_procedure_definition))); + } + context.converted_template_type.external_methods.Add( + new procedure_definition_info(context.converted_namespace, _procedure_definition)); + context.converted_template_type = null; + return; + } + //\ssyy + if (context.top_function == null) + { + return; + } + + // frninja 20/05/16 - ставим флаг is_yield_helper + if (context.top_function is common_namespace_function_node) + { + (context.top_function as common_namespace_function_node).is_yield_helper = _procedure_definition.proc_header.is_yield_helper; + } + // end frninja + + if (context.converted_explicit_interface_type != null) + (context.top_function as common_method_node).explicit_interface = context.converted_explicit_interface_type; + if (has_dll_import_attribute(context.top_function)) + { + if (_procedure_definition.proc_body != null) + if (!is_pinvoke(_procedure_definition.proc_body)) + AddError(get_location(_procedure_definition.proc_body), "EXPECTED_EXTERNAL_STATEMENT"); + must_visit_body = true; + } + + if (contextChanger.IsActive()) + { + must_visit_body = true; + } + + if (context.top_function.return_value_type is undefined_type) // значит, это короткое определение функции, и тело есть, и его надо обойти + { + must_visit_body = true; + } + + // try + { + + if (context.top_function.is_forward) + { + if (_procedure_definition.proc_body != null) + { + AddError(context.top_function.loc, "FORWARD_DEFINITION_WITH_FUNCTION_BODY"); + } + } + else + { + if (must_visit_body) + { + common_method_node cmn = context.top_function as common_method_node; + + // frninja 3/06/16 - ставим флаг is_yield_helper для предописанных методов класса + if (cmn != null) + cmn.is_yield_helper = _procedure_definition.proc_header.is_yield_helper; + // end frninja + + if (cmn != null && !cmn.IsStatic) + { + //if (cmn.find_only_in_namespace(compiler_string_consts.self_word) == null) + //self variable + //добавляем self, обращение к ней заменяется на this_node + type_node self_type = cmn.cont_type; + if (cmn.cont_type.is_generic_type_definition) + self_type = cmn.cont_type.get_instance(cmn.cont_type.generic_params.ConvertAll(o => (type_node)o)); + local_variable lv = new local_variable(compiler_string_consts.self_word, self_type, cmn, null); + cmn.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv)); + cmn.self_variable = lv; + } + if (_procedure_definition.proc_body != null) + { + hard_node_test_and_visit(_procedure_definition.proc_body); + } + + // SSM 12/04/16 - short func definitions - calc return_value_type + var ttt = context.top_function.return_value_type; + if (ttt is undefined_type) + { + var cd = context.top_function.function_code as statements_list; + + if (cd == null || cd.statements == null || cd.statements.Count == 0) + { + AddError(context.top_function.loc, "IMPOSSIBLE!SHORT_FUNC_WITHOUT_BODY"); + } + + // Проблема в том, что если в теле короткого определения функции - лямбда + // и происходит захват переменной, то в тело выносится вызов конструктора сгенерированного класса + // Поэтому result := ... - это не первый оператор, а последний!!! + statement_node aa = cd.statements[cd.statements.Count-1]; + var bfc = aa as basic_function_call; + if (bfc != null) + { + var ttt1 = bfc.type; + context.top_function.return_value_type = ttt1; + context.top_function.var_definition_nodes_list[0].type = ttt1; + } + } + + add_clip_for_set(context.top_function); + } + else // if (!must_visit_body) + { + context.add_method_header(_procedure_definition, context.top_function); + } + + } + } + //finally + { + if (_procedure_definition.proc_header.name.class_name != null) + { + // frninja 03/06/16 - убираем мусорные методы-хелперы yield + if (context._ctn != null && (context.top_function is common_method_node) && (context.top_function as common_method_node).is_yield_helper) + { + context._ctn.methods.remove(context.top_function as common_method_node); + } + // end frninja + context.leave_type_method(); + } + /*else + { + if (context._cmn != null && context._cmn.functions != null && (context.top_function is common_namespace_function_node) && + (context.top_function as common_namespace_function_node).is_yield_helper && + context.top_function.name.ToLower().StartsWith(" attrs) + { + foreach (SyntaxTree.procedure_attribute attr in attrs) + { + if (attr.attribute_type == PascalABCCompiler.SyntaxTree.proc_attribute.attr_static) + { + return true; + } + } + return false; + } + + bool has_extensionmethod_attr(List attrs) + { + foreach (SyntaxTree.procedure_attribute attr in attrs) + { + if (attr.attribute_type == PascalABCCompiler.SyntaxTree.proc_attribute.attr_extension) + { + return true; + } + } + return false; + } + + private bool has_var_char_parameters(common_function_node fn) + { + for (int i=0; i p.idents.idents).Where(id => id.name.ToLower() == "self"); + if (q != null && q.Count() > 0) + { + var sid = q.First(); + AddError(get_location(sid), "SELF_NOT_ALLOWED_IN_METHOD_PARAMS"); + } + } + + current_function_header = null; + if (context.converted_template_type != null) + { + return; + } + if (_procedure_header.template_args != null) + { + visit_generic_params(context.top_function, _procedure_header.template_args.idents); + } + if (_procedure_header.where_defs != null) + { + visit_where_list(_procedure_header.where_defs); + } + weak_node_test_and_visit(_procedure_header.parameters); + if (_procedure_header.name.class_name != null) + with_class_name = true; + if (_procedure_header.class_keyword && !has_static_attr(_procedure_header.proc_attributes.proc_attributes)) + { + SyntaxTree.procedure_attribute pa = new SyntaxTree.procedure_attribute(PascalABCCompiler.SyntaxTree.proc_attribute.attr_static); + pa.source_context = _procedure_header.source_context; + _procedure_header.proc_attributes.proc_attributes.Insert(0, pa); + } + weak_node_test_and_visit(_procedure_header.proc_attributes); + with_class_name = false; + CheckOverrideOrReintroduceExpectedWarning(get_location(_procedure_header)); + if (context.top_function != null && context.top_function is common_namespace_function_node && (context.top_function as common_namespace_function_node).ConnectedToType != null && !context.top_function.IsOperator) + { + concrete_parameter_type cpt = concrete_parameter_type.cpt_none; + SemanticTree.parameter_type pt = PascalABCCompiler.SemanticTree.parameter_type.value; + if ((context.top_function as common_namespace_function_node).ConnectedToType.is_value_type) + { + cpt = concrete_parameter_type.cpt_var; + pt = PascalABCCompiler.SemanticTree.parameter_type.var; + } + type_node cur_tn = (context.top_function as common_namespace_function_node).ConnectedToType; + type_node self_type = cur_tn; + if (context.top_function.generic_params != null && self_type.is_generic_type_definition) + { + self_type = self_type.get_instance(context.top_function.get_generic_params_list()); + } + if (!has_extensionmethod_attr(_procedure_header.proc_attributes.proc_attributes)) + { + common_parameter cp = new common_parameter(compiler_string_consts.self_word, self_type, pt, + context.top_function, cpt, null, null); + + context.top_function.parameters.AddElementFirst(cp); + context.top_function.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(cp)); + } + } + + if (_procedure_header is SyntaxTree.constructor) + { + common_method_node cmnode = context.top_function as common_method_node; + if (cmnode != null) + { + cmnode.is_constructor = true; + cmnode.return_value_type = context.converted_type; + + } + else if (context.top_function is common_namespace_function_node && (context.top_function as common_namespace_function_node).ConnectedToType != null) + AddError(get_location(_procedure_header), "EXTENSION_CONSTRUCTOR_NOT_ALLOWED"); + else + if (context.converted_compiled_type != null) + AddError(get_location(_procedure_header), "EXTENSION_CONSTRUCTOR_NOT_ALLOWED"); + } + + if (context.top_function.IsOperator) + { + if (context.top_function is common_method_node) + { + common_method_node cmmn = context.top_function as common_method_node; + if (cmmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + { + AddError(get_location(_procedure_header), "OVERLOADED_OPERATOR_MUST_BE_STATIC_FUNCTION"); + } + } + } + bool unique = context.close_function_params(body_exists); + + if (context.converted_type != null && context.converted_type.IsInterface) + { + if (body_exists) + { + AddError(new InterfaceFunctionWithBody(get_location(_procedure_header))); + } + common_method_node cmnode = context.top_function as common_method_node; + context.set_virtual_abstract(cmnode); + } + + if (context.converted_type != null) + { + common_method_node cmnode = context.top_function as common_method_node; + if (cmnode != null && cmnode.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract && body_exists) + { + AddError(new AbstractMethodWithBody(get_location(_procedure_header))); + } + } + if (_procedure_header.where_defs != null) + { + if (!unique && false) + { + AddError(get_location(_procedure_header.where_defs), "WHERE_SECTION_MUST_BE_ONLY_IN_FIRST_DECLARATION"); + } + } + assign_doc_info(context.top_function,_procedure_header); + if (_procedure_header.attributes != null) + { + make_attributes_for_declaration(_procedure_header, context.top_function); + } + if (context.converted_type != null && has_dll_import_attribute(context.top_function)) + AddError(get_dll_import_attribute(context.top_function).location, "DLLIMPORT_ATTRIBUTE_CANNOT_BE_APPLIED_TO_METHOD"); + if (!body_exists) + { + if (_procedure_header.name.class_name != null && context.converted_explicit_interface_type != null) + { + AddError(get_location(_procedure_header), "EXPLICIT_IMPLEMENTATION_EXPECTED"); + } + if ((context.top_function.semantic_node_type == semantic_node_type.common_method_node) + || ((context.func_stack_size_is_one()) && (_is_interface_part))) + { + context.leave_block(); + if (_procedure_header.name.class_name != null && context.converted_compiled_type != null) + context.converted_compiled_type = null; + } + } + body_exists = false; + + } + + public override void visit(SyntaxTree.procedure_header _procedure_header) + { + visit_procedure_header(_procedure_header); + } + + public override void visit(SyntaxTree.procedure_attributes_list _procedure_attributes_list) + { + bool is_override = false; + bool is_virtual = false; + bool is_abstract = false; + string override_proc_attr=null; + string virtual_proc_attr=null; + string abstract_proc_attr = null; + for (int i = 0; i < _procedure_attributes_list.proc_attributes.Count; i++) + { + switch (_procedure_attributes_list.proc_attributes[i].attribute_type) + { + case SyntaxTree.proc_attribute.attr_abstract: + { + is_abstract = true; + abstract_proc_attr = _procedure_attributes_list.proc_attributes[i].name; + } + break; + case SyntaxTree.proc_attribute.attr_override: + { + is_override = true; + override_proc_attr = _procedure_attributes_list.proc_attributes[i].name; + } + break; + case SyntaxTree.proc_attribute.attr_virtual: + { + is_virtual = true; + virtual_proc_attr = _procedure_attributes_list.proc_attributes[i].name; + } + break; + } + } + context.top_function.is_overload = true; // SSM 12/08/15 + context.last_created_function.symbol_kind = symbol_kind.sk_overload_function; + bool is_forward = false; + for (int i = 0; i < _procedure_attributes_list.proc_attributes.Count; i++) + { + convertion_data_and_alghoritms.check_node_parser_error(_procedure_attributes_list.proc_attributes[i]); + for (int j = 0; j < i; j++) + { + if (_procedure_attributes_list.proc_attributes[i].attribute_type == + _procedure_attributes_list.proc_attributes[j].attribute_type) + { + AddError(new DuplicateAttributeDefinition(get_location(_procedure_attributes_list.proc_attributes[j]), + get_location(_procedure_attributes_list.proc_attributes[i]))); + } + } + + switch (_procedure_attributes_list.proc_attributes[i].attribute_type) + { + case SyntaxTree.proc_attribute.attr_overload:// ничего не делать - это и так есть + { + break; + } + case SyntaxTree.proc_attribute.attr_forward: + { + if (with_class_name) + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "DIRECTIVE_{0}_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name); + //(ssyy) В интерфейсах аттрибуты недопустимы + if (context.converted_type != null && context.converted_type.IsInterface) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "ATTRIBUTES_IN_INTERFACE_MEMBER"); + } + common_namespace_function_node top_function = context.top_function as common_namespace_function_node; + if (top_function != null && top_function.ConnectedToType != null) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "FORWARD_EXTENSION_METHODS_NOT_ALLOWED"); + } + + is_forward = true; + break; + } + case SyntaxTree.proc_attribute.attr_virtual: + { + + if (with_class_name) + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "DIRECTIVE_{0}_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name); + //(ssyy) В интерфейсах аттрибуты недопустимы + if (context.converted_type != null && context.converted_type.IsInterface) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "ATTRIBUTES_IN_INTERFACE_MEMBER"); + } + + //(ssyy) В записях нет виртуальных функций + if (context.converted_type != null && context.converted_type.is_value) + { + AddError(new VirtualMethodInRecord( + get_location(_procedure_attributes_list.proc_attributes[i]))); + } + + common_function_node ccfn = context.top_function; + if (ccfn.semantic_node_type != semantic_node_type.common_method_node) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "{0}_KEYWORD_ALLOWED_ONLY_WITH_METHOD", _procedure_attributes_list.proc_attributes[i].name); + } + common_method_node cmn = ccfn as common_method_node; + if (cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "CAN_NOT_BE_VIRTUAL_STATIC_METHOD"); + } + if (is_override) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "USING_MODIFIERS{0}_{1}_TOGETHER_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name,override_proc_attr); + } + if (!context.converted_type.IsAbstract || true) + { + is_virtual = true; + virtual_proc_attr = _procedure_attributes_list.proc_attributes[i].name; + if (!is_abstract) + context.set_virtual(cmn); + } + break; + } + case SyntaxTree.proc_attribute.attr_override: + case SyntaxTree.proc_attribute.attr_reintroduce: + { + if (with_class_name) + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "DIRECTIVE_{0}_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name); + //(ssyy) В интерфейсах аттрибуты недопустимы + if (context.converted_type != null && context.converted_type.IsInterface) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "ATTRIBUTES_IN_INTERFACE_MEMBER"); + } + + common_function_node ccfn = context.top_function; + if (ccfn.return_value_type is undefined_type) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "OVERRIDE_NOT_ALLOWED_FOR_SHORT_FUNCTIONS"); + } + if (ccfn.semantic_node_type != semantic_node_type.common_method_node) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "{0}_KEYWORD_ALLOWED_ONLY_WITH_METHOD", _procedure_attributes_list.proc_attributes[i].name); + } + common_method_node cmn = ccfn as common_method_node; + if (cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "CAN_NOT_BE_VIRTUAL_STATIC_METHOD"); + } + if (_procedure_attributes_list.proc_attributes[i].attribute_type == SyntaxTree.proc_attribute.attr_reintroduce) + { + cmn.IsReintroduce = true; + if (is_abstract) + cmn.newslot_awaited = true; + break; + } + if (_procedure_attributes_list.proc_attributes[i].attribute_type == SyntaxTree.proc_attribute.attr_override && is_virtual) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]),"USING_MODIFIERS{0}_{1}_TOGETHER_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name,virtual_proc_attr); + } + if (_procedure_attributes_list.proc_attributes[i].attribute_type == SyntaxTree.proc_attribute.attr_override) + { + is_override = true; + override_proc_attr = _procedure_attributes_list.proc_attributes[i].name; + } + + context.set_override(cmn); + if (is_abstract) + { + cmn.polymorphic_state = SemanticTree.polymorphic_state.ps_virtual_abstract; + + } + if (is_override && _procedure_attributes_list.Parent is procedure_header ph && ph.where_defs != null) + AddError(cmn.loc, "OVERRIDE_METHODS_CANNOT_CONTAIN_WHERE_SECTION"); + + if (cmn.field_access_level < cmn.overrided_method.field_access_level) + AddError(cmn.loc, "CAN_NOT_BE_DOWN_ACCESS_LEVEL_FOR_METH"); + break; + } + case SyntaxTree.proc_attribute.attr_static: + { + if (with_class_name) + { + if (context.top_function != null) + { + context.top_function.polymorphic_state = PascalABCCompiler.SemanticTree.polymorphic_state.ps_static; + break; + } + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "DIRECTIVE_{0}_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name); + } + //(ssyy) В интерфейсах аттрибуты недопустимы + if (context.converted_type != null && context.converted_type.IsInterface) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "ATTRIBUTES_IN_INTERFACE_MEMBER"); + } + + common_function_node ccfn = context.top_function; + if (ccfn.semantic_node_type != semantic_node_type.common_method_node) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "STATIC_KEYWORD_ALLOWED_ONLY_WITH_METHOD"); + } + common_method_node cmn = ccfn as common_method_node; + if (cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "CAN_NOT_BE_VIRTUAL_STATIC_METHOD"); + } + if (cmn.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "CANNOT_BE_ABSTRACT_STATIC_METHOD"); + } + cmn.polymorphic_state = SemanticTree.polymorphic_state.ps_static; + break; + } + case SyntaxTree.proc_attribute.attr_abstract: + { + if (with_class_name) + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "DIRECTIVE_{0}_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name); + if (context.converted_type != null && context.converted_type.IsInterface) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "ATTRIBUTES_IN_INTERFACE_MEMBER"); + } + common_function_node ccfn = context.top_function; + common_method_node cmn = ccfn as common_method_node; + + if (ccfn.semantic_node_type != semantic_node_type.common_method_node) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "{0}_KEYWORD_ALLOWED_ONLY_WITH_METHOD", _procedure_attributes_list.proc_attributes[i].name); + } + if (context.converted_type != null && context.converted_type.is_value) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "ABSTRACT_METHOD_IN_RECORD"); + } + if (ccfn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "CANNOT_BE_ABSTRACT_STATIC_METHOD"); + } + if (cmn.is_constructor) + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "DIRECTIVE_{0}_NOT_ALLOWED", _procedure_attributes_list.proc_attributes[i].name); + cmn.polymorphic_state = SemanticTree.polymorphic_state.ps_virtual_abstract; + if (context.converted_type.IsSealed) + AddError(get_location(_procedure_attributes_list.proc_attributes[i]), "ABSTRACT_METHOD_IN_SEALED_CLASS"); + context.converted_type.SetIsAbstract(true); + if (cmn.IsReintroduce) + cmn.newslot_awaited = true; + break; + } + case proc_attribute.attr_extension: + { + if (is_forward) + AddError(get_location(_procedure_attributes_list), "EXTENSIONMETHOD_KEYWORD_NOT_ALLOWED"); + if (context.converted_compiled_type != null) + AddError(get_location(_procedure_attributes_list), "EXTENSIONMETHOD_KEYWORD_NOT_ALLOWED"); + if (in_interface_part) + AddError(get_location(_procedure_attributes_list), "EXTENSION_METHODS_IN_INTERFACE_PART_NOT_ALLOWED"); + if (!(context.top_function is common_namespace_function_node)) + AddError(get_location(_procedure_attributes_list), "EXTENSION_ATTRIBUTE_ONLY_FOR_NAMESPACE_FUNCTIONS_ALLOWED"); + if (context.top_function.parameters.Count == 0) + AddError(context.top_function.loc, "EXTENSION_METHODS_MUST_HAVE_LEAST_ONE_PARAMETER"); + if (!context.top_function.IsOperator && context.top_function.parameters[0].parameter_type != SemanticTree.parameter_type.value + && !(context.top_function.parameters[0].type is compiled_type_node ctn && ctn.compiled_type == typeof(string))) + AddError(context.top_function.loc, "FIRST_PARAMETER_SHOULDBE_ONLY_VALUE_PARAMETER"); + if (!context.top_function.IsOperator && context.top_function.parameters[0].name.ToLower() != compiler_string_consts.self_word) + AddError(context.top_function.loc,"FIRST_PARAMETER_MUST_HAVE_NAME_SELF"); + + common_namespace_function_node top_function = context.top_function as common_namespace_function_node; + top_function.ConnectedToType = context.top_function.parameters[0].type; + if (top_function.ConnectedToType.Scope == null && top_function.ConnectedToType is compiled_type_node) + { + (top_function.ConnectedToType as compiled_type_node).init_scope(); + } + if (top_function.ConnectedToType.Scope == null) + AddError(context.top_function.loc, "EXTENSION_METHODS_FOR_CONSTRUCTED_TYPES_NOT_ALLOWED"); + SymbolInfo si = new SymbolInfo(context.top_function); + si.symbol_kind = symbol_kind.sk_overload_function; + top_function.ConnectedToType.Scope.AddSymbol(top_function.name, si); + if (top_function.ConnectedToType.type_special_kind == SemanticTree.type_special_kind.array_kind /*&& top_function.ConnectedToType.element_type.is_generic_parameter*/) + top_function.ConnectedToType.base_type.Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function)); + else if (top_function.ConnectedToType.is_generic_parameter) + top_function.ConnectedToType.base_type.Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function)); + else if (top_function.ConnectedToType is compiled_type_node && top_function.ConnectedToType.is_generic_type_instance && top_function.ConnectedToType.original_generic.Scope != null) + top_function.ConnectedToType.original_generic.Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function)); + else if (top_function.ConnectedToType is compiled_generic_instance_type_node && top_function.ConnectedToType.original_generic.Scope != null) + top_function.ConnectedToType.original_generic.Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function)); + else if (top_function.ConnectedToType.IsDelegate && top_function.ConnectedToType.base_type.IsDelegate) + compiled_type_node.get_type_node(typeof(Delegate)).Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function)); + else if (top_function.ConnectedToType.type_special_kind == SemanticTree.type_special_kind.typed_file && top_function.ConnectedToType.element_type.is_generic_parameter && SystemLibrary.SystemLibInitializer.TypedFileType.sym_info != null) + (SystemLibrary.SystemLibInitializer.TypedFileType.sym_info as type_node).Scope.AddSymbol(top_function.name, new SymbolInfo(context.top_function)); + if (top_function.ConnectedToType.IsDelegate && context.top_function.IsOperator && (context.top_function.name == "+" || context.top_function.name == "-" || context.top_function.name == "+=" || context.top_function.name == "-=")) + AddError(get_location(_procedure_attributes_list), "CANNOT_EXTEND_STANDARD_OPERATORS_FOR_DELEGATE"); + if (context.top_function.IsOperator && (context.top_function.name == compiler_string_consts.implicit_operator_name || context.top_function.name == compiler_string_consts.explicit_operator_name) && context.top_function.parameters.Count == 1 && context.top_function.return_value_type != null) + { + if (!(context.top_function.return_value_type is compiled_type_node) && !(context.top_function.return_value_type is compiled_generic_instance_type_node) || !(context.top_function.parameters[0].type is compiled_type_node) && !(context.top_function.parameters[0].type is compiled_generic_instance_type_node)) + ;//AddError(get_location(_procedure_attributes_list), "IMPLICIT_EXPLICIT_OPERATOR_EXTENSION_ONLY_FOR_COMPILED_CLASSES_ALLOWED"); + } + break; + } + default: + { + throw new NotSupportedError(get_location(_procedure_attributes_list.proc_attributes[i])); + } + } + } + } + + private bool first_param=false; + public override void visit(SyntaxTree.formal_parameters _formal_parametres) + { + bool default_value_met = false; + bool params_met = false; + first_param = true; + foreach (SyntaxTree.typed_parameters tp in _formal_parametres.params_list) + { + if (params_met) + { + AddError(get_location(tp), "ONLY_LAST_PARAMETER_CAN_BE_PARAMS"); + } + if (tp.param_kind == PascalABCCompiler.SyntaxTree.parametr_kind.params_parametr) + { + params_met = true; + if (default_value_met) + { + AddError(get_location(tp), "FUNCTION_WITH_PARAMS_PARAMETER_CAN_NOT_HAVE_DEFAULT_PARAMETERS"); + } + } + hard_node_test_and_visit(tp); + first_param = false; + if ((default_value_met) && (tp.inital_value == null)) + { + AddError(new NeedDefaultValueForParameter(get_location(tp))); + } + + if (tp.inital_value != null) + { + default_value_met = true; + } + } + first_param = false; + common_method_node cnode = context.top_function as common_method_node; + parameter_list pars = context.top_function.parameters; + if (cnode != null && cnode.IsOperator) + { + + if (cnode.name != compiler_string_consts.implicit_operator_name && cnode.name != compiler_string_consts.explicit_operator_name) + { + bool all_types_mismatch = true; + foreach (parameter par in pars) + { + //if (par.type == cnode.comperehensive_type) + if (convertion_data_and_alghoritms.eq_type_nodes(par.type, cnode.comperehensive_type as type_node)) + { + all_types_mismatch = false; + break; + } + } + if (all_types_mismatch) + { + AddError(cnode.loc, "TYPE_OF_ONE_OR_MORE_OPERATOR_PARAMETERS_MUST_BE_{0}", ((type_node)(cnode.comperehensive_type)).PrintableName); + } + } + if (pars.Count > 0 && pars[pars.Count - 1].is_params) + { + AddError(convertion_data_and_alghoritms.get_location(pars[pars.Count - 1]), "PARAMS_IN_OPERATOR"); + } + + } + if (context.top_function.IsOperator) + { + int pcount = name_reflector.get_params_count(context.top_function.name); + if (pcount != pars.Count) + { + if (context.top_function.name != compiler_string_consts.minus_name && context.top_function.name != compiler_string_consts.plus_name) + AddError(context.top_function.loc, "OPERATOR_{0}_PARAMETERS_COUNT_MUST_EQUAL_{1}", context.top_function.name, pcount); + else + if (pars.Count != 1 && pars.Count != 2) + AddError(context.top_function.loc, "OPERATOR_{0}_PARAMETERS_COUNT_MUST_EQUAL_{1}", context.top_function.name, pcount); + } + } + } + + private void check_array_on_complex_type(SyntaxTree.array_type type) + { + SyntaxTree.array_type arr = type as SyntaxTree.array_type; + if (arr.indexers != null && arr.indexers.indexers.Count > 0 && arr.indexers.indexers[0] != null) + AddError(get_location(type), "STRUCT_TYPE_DEFINITION_IN_FORMAL_PARAM"); + if (arr.elements_type is SyntaxTree.array_type) + check_array_on_complex_type(arr.elements_type as SyntaxTree.array_type); + else if (arr.elements_type is SyntaxTree.class_definition) + AddError(get_location(arr.elements_type), "STRUCT_TYPE_DEFINITION_IN_FORMAL_PARAM"); + else if (arr.elements_type is SyntaxTree.set_type_definition) + check_set_on_complex_type(arr.elements_type as set_type_definition); + else if (arr.elements_type is SyntaxTree.file_type) + check_file_on_complex_type(arr.elements_type as file_type); + } + + private void check_set_on_complex_type(SyntaxTree.set_type_definition type) + { + SyntaxTree.set_type_definition set = type as SyntaxTree.set_type_definition; + if (set.of_type is SyntaxTree.array_type) + check_array_on_complex_type(set.of_type as SyntaxTree.array_type); + else if (set.of_type is SyntaxTree.class_definition) + AddError(get_location(set.of_type), "STRUCT_TYPE_DEFINITION_IN_FORMAL_PARAM"); + else if (set.of_type is SyntaxTree.file_type) + check_file_on_complex_type(set.of_type as file_type); + else if (set.of_type is SyntaxTree.set_type_definition) + check_set_on_complex_type(set.of_type as set_type_definition); + } + + private void check_file_on_complex_type(SyntaxTree.file_type type) + { + SyntaxTree.file_type file = type as SyntaxTree.file_type; + if (file.file_of_type is SyntaxTree.array_type) + check_array_on_complex_type(file.file_of_type as SyntaxTree.array_type); + else if (file.file_of_type is SyntaxTree.class_definition) + AddError(get_location(file.file_of_type), "STRUCT_TYPE_DEFINITION_IN_FORMAL_PARAM"); + else if (file.file_of_type is SyntaxTree.file_type) + check_file_on_complex_type(file.file_of_type as file_type); + else if (file.file_of_type is SyntaxTree.set_type_definition) + check_set_on_complex_type(file.file_of_type as set_type_definition); + } + + public void check_parameter_on_complex_type(SyntaxTree.type_definition type) + { + SyntaxTree.array_type arr = type as SyntaxTree.array_type; + if (type is SyntaxTree.class_definition || /*type is SyntaxTree.enum_type_definition ||*/ + (arr != null && arr.indexers != null && arr.indexers.indexers.Count > 0 && arr.indexers.indexers[0] != null)) + { + AddError(get_location(type), "STRUCT_TYPE_DEFINITION_IN_FORMAL_PARAM"); + } + if (arr != null) + { + check_array_on_complex_type(arr); + return; + } + if (type is SyntaxTree.set_type_definition) + { + check_set_on_complex_type(type as SyntaxTree.set_type_definition); + return; + } + else if (type is SyntaxTree.file_type) + { + check_file_on_complex_type(type as SyntaxTree.file_type); + return; + } + if (context.top_function is common_method_node && (context.converted_type.IsInterface || context.top_function.polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract ) + && (type is function_header || type is procedure_header)) + AddError(get_location(type), "ANONYMOUS_DELEGATE_IN_INTERFACE_NOT_ALLOWED"); + } + + public override void visit(SyntaxTree.typed_parameters _typed_parametres) + { + SemanticTree.parameter_type par_type = SemanticTree.parameter_type.value; + concrete_parameter_type cpt = concrete_parameter_type.cpt_none; + bool is_params = false; + switch (_typed_parametres.param_kind) + { + case SyntaxTree.parametr_kind.const_parametr: + { + par_type = SemanticTree.parameter_type.value; + cpt = concrete_parameter_type.cpt_const; + break; + } + case SyntaxTree.parametr_kind.none: + { + par_type = SemanticTree.parameter_type.value; + cpt = concrete_parameter_type.cpt_none; + break; + } + case SyntaxTree.parametr_kind.out_parametr: + { + par_type = SemanticTree.parameter_type.var; + cpt = concrete_parameter_type.cpt_var; + break; + } + case SyntaxTree.parametr_kind.var_parametr: + { + par_type = SemanticTree.parameter_type.var; + cpt = concrete_parameter_type.cpt_var; + break; + } + case PascalABCCompiler.SyntaxTree.parametr_kind.params_parametr: + { + is_params = true; + break; + } + } + common_parameter com_par = null; + if (is_params) + { + if (_typed_parametres.idents.idents.Count != 1) + { + AddError(get_location(_typed_parametres.idents.idents[1]), "ONLY_ONE_PARAMS_PARAMETER_ALLOWED"); + } + } + foreach (SyntaxTree.ident id in _typed_parametres.idents.idents) + { + com_par = context.add_parameter(id.name, par_type, cpt, get_location(id)); + if (is_params) + { + com_par.intrenal_is_params = true; + } + } + + if (_typed_parametres.vars_type == null) + throw new NotSupportedError(get_location(_typed_parametres)); + + check_parameter_on_complex_type(_typed_parametres.vars_type); + type_node tn = convert_strong(_typed_parametres.vars_type); + if (tn.IsStatic) + AddError(get_location(_typed_parametres), "VARIABLES_OF_STATIC_CLASS_NOT_ALLOWED"); + if (_typed_parametres.vars_type is function_header || _typed_parametres.vars_type is procedure_header) + { + check_delegate_on_generic_parameters(tn as common_type_node, get_location(_typed_parametres.vars_type)); + } + check_for_type_allowed(tn,get_location(_typed_parametres.vars_type)); + if (is_params) + { + internal_interface ii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface); + if (ii == null) + { + AddError(get_location(_typed_parametres.vars_type), "ONLY_UNSIZED_ARRAY_PARAMS_PARAMETER_ALLOWED"); + } + } + com_par.type = tn; + foreach (SyntaxTree.ident id in _typed_parametres.idents.idents) + { + if (_typed_parametres.attributes != null) + { + make_attributes_for_declaration(_typed_parametres, com_par); + } + + } + com_par.type = tn; + context.in_parameters_block = true; + + //TODO: Доделать параметры со значениями по умолчанию. + if (_typed_parametres.inital_value != null) + { + if (_typed_parametres.idents.idents.Count != 1) + { + AddError(new OnlyOneParameterNameWithDefaultValueAllowed(get_location(_typed_parametres))); + } + if (cpt == concrete_parameter_type.cpt_var) + { + AddError(new VarParametersCanNotHaveDefaultValue(get_location(_typed_parametres))); + } + if (cpt == concrete_parameter_type.cpt_const) + { + AddError(get_location(_typed_parametres), "CONST_PARAMETERS_CANNOT_HAVE_DEFAULT_VALUE"); + } + context.top_function.num_of_default_variables = context.top_function.num_of_default_variables + 1; + expression_node def_val_expr = convert_strong_to_constant_node(_typed_parametres.inital_value); + com_par.default_value = convertion_data_and_alghoritms.convert_type(def_val_expr, tn); + } + context.in_parameters_block = false; + context.close_var_definition_list(tn, null); + } + + private void check_delegate_on_generic_parameters(common_type_node ctn, location loc) + { + if (ctn == null) + return; + foreach (common_method_node cmn in ctn.methods) + { + if (cmn.name == "Invoke") + { + foreach (common_parameter prm in cmn.parameters) + { + if (is_instance_of_generic_parameter(prm.type)) + AddError(loc, "ANONYMOUS_FUNCTION_TYPE_WITH_GENERICS"); + } + if (cmn.return_value_type != null && is_instance_of_generic_parameter(cmn.return_value_type)) + AddError(loc, "ANONYMOUS_FUNCTION_TYPE_WITH_GENERICS"); + } + } + } + + private bool is_instance_of_generic_parameter(type_node tn) + { + if (tn.is_generic_parameter) + return true; + else if (tn.is_generic_type_instance) + { + foreach (type_node inst_tn in tn.instance_params) + if (is_instance_of_generic_parameter(inst_tn)) + return true; + } + return false; + } + + public override void visit(SyntaxTree.procedure_attribute _procedure_attribute) + { + throw new NotSupportedError(get_location(_procedure_attribute)); + } + + public override void visit(SyntaxTree.label_definitions _label_definitions) + { + /*if (context.converting_block() == block_type.type_block && + context.converted_type.IsInterface) + { + throw new InvalidInterfaceMember(get_location(_label_definitions)); + }*/ + foreach (SyntaxTree.ident id in _label_definitions.labels.idents) + { + context.add_label_declaration(id.name, get_location(id)); + } + } + + private bool depended_from_generic_parameter(type_node tn) + { + //Ivan 1.09.08 added + if (tn == null) + return false; + if (tn.is_generic_parameter) + return true; + if (tn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.set_type) + { + return depended_from_generic_parameter(tn.element_type); + } + if (tn.type_special_kind == PascalABCCompiler.SemanticTree.type_special_kind.array_kind) + { + return depended_from_generic_parameter(tn.element_type); + } + ref_type_node rtn = tn as ref_type_node; + if (rtn != null) + { + return depended_from_generic_parameter(rtn.pointed_type); + } + generic_instance_type_node gitn = tn as generic_instance_type_node; + if (gitn == null) + return false; + foreach (type_node param in gitn.generic_parameters) + { + if (depended_from_generic_parameter(param)) + return true; + } + return false; + } + + private bool is_unsized_array(SyntaxTree.indexers_types indexes, out int rank) + { + rank = 1; + if (indexes == null) + return true; + bool wait_empty = false; + for (int i=0; i 32) + AddError(get_location(_array_type.indexers), "ARRAY_RANK_CANNOT_BE_GREATER_32"); + type_node ret = null; + type_node et = convert_strong(_array_type.elements_type); + //if (et == SystemLibrary.SystemLibrary.void_type) + //AddError(new VoidNotValid(get_location(_array_type.elemets_types))); + check_for_type_allowed(et,get_location(_array_type.elements_type)); + check_using_static_class(et, get_location(_array_type.elements_type)); + ret = convertion_data_and_alghoritms.type_constructor.create_unsized_array(et, + context.converted_namespace, rank, get_location(_array_type)); + return_value(ret); + return; + } + type_node_list ind_types = new type_node_list(); + foreach (SyntaxTree.type_definition td in _array_type.indexers.indexers) + { + type_node tn = convert_strong(td); + internal_interface ii = tn.get_internal_interface(internal_interface_kind.ordinal_interface); + if (ii == null) + { + AddError(new OrdinalTypeExpected(get_location(td))); + } + if (tn.IsEnum && tn is common_type_node) + { + common_type_node enum_ctn = tn as common_type_node; + int c = 0; + for (int i = 0; i < enum_ctn.const_defs.Count; i++) + { + class_constant_definition ccdn = enum_ctn.const_defs[i]; + if (ccdn.constant_value != null) + { + int nextc = Convert.ToInt32(ccdn.constant_value.value); + if (nextc - c != 1 && i != 0) + AddError(get_location(td), "ENUM_MUST_HAVE_SEQUENCED_VALUES"); + else if (nextc != 0 && i == 0) + AddError(get_location(td), "ENUM_MUST_HAVE_SEQUENCED_VALUES"); + c = nextc; + } + } + } + if (tn.type_special_kind == SemanticTree.type_special_kind.diap_type) + { + if (tn.base_type == SystemLibrary.SystemLibrary.uint_type || tn.base_type == SystemLibrary.SystemLibrary.int64_type || + tn.base_type == SystemLibrary.SystemLibrary.uint64_type) + //ordinal_type_interface oti = tn.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; + AddError(get_location(td), "RANGE_TOO_LARGE"); + if (tn.base_type == SystemLibrary.SystemLibrary.integer_type) + { + Int64 low = ((tn as SemanticTree.ICommonTypeNode).lower_value as int_const_node).constant_value; + Int64 high = ((tn as SemanticTree.ICommonTypeNode).upper_value as int_const_node).constant_value; + if (high-low >= int.MaxValue) + AddError(get_location(td), "RANGE_TOO_LARGE"); + } + } + else if (tn == SystemLibrary.SystemLibrary.uint_type || tn == SystemLibrary.SystemLibrary.int64_type || + tn == SystemLibrary.SystemLibrary.uint64_type || tn == SystemLibrary.SystemLibrary.integer_type) + AddError(get_location(td), "RANGE_TOO_LARGE"); + ind_types.AddElement(tn); + } + type_node elem_type = convert_strong(_array_type.elements_type); + //TODO: Сделать и массивы, связанные с generics! + if (depended_from_generic_parameter(elem_type)) + { + throw new NotSupportedError(get_location(_array_type.elements_type)); + } + check_for_type_allowed(elem_type,get_location(_array_type.elements_type)); + check_using_static_class(elem_type, get_location(_array_type.elements_type)); + for (int i = ind_types.Count - 1; i >= 0; i--) + { + internal_interface ii = ind_types[i].get_internal_interface(internal_interface_kind.ordinal_interface); + ordinal_type_interface oti_ind = (ordinal_type_interface)ii; + elem_type = convertion_data_and_alghoritms.type_constructor.get_array_type(oti_ind, elem_type, + context.converted_namespace, get_location(_array_type)); + } + return_value(elem_type); + } + + public override void visit(SyntaxTree.indexers_types _indexers_types) + { + throw new NotSupportedError(get_location(_indexers_types)); + } + + private constant_node convert_strong_to_constant_node(SyntaxTree.expression expr) + { + expression_node exp = convert_strong(expr); + var is_const_section = (expr.Parent != null && (expr.Parent is const_definition)); + + var is_userdefined = false; + var cnf = exp as common_namespace_function_call; + if (cnf != null) + { + is_userdefined = ! (cnf.function_node.namespace_node.namespace_name.Equals("PABCSystem") || cnf.function_node.namespace_node.namespace_name.Equals("PABCSystem_implementation______")); + } + return convert_strong_to_constant_node(exp, exp.type, is_const_section && is_userdefined, is_const_section); + } + + public expression_node convert_strong_to_constant_or_function_call_for_varinit(expression_node exp) + { + return convert_strong_to_constant_or_function_call_for_varinit(exp, exp.type); + } + + private expression_node convert_strong_to_constant_or_function_call_for_varinit(expression_node exp, type_node tn) + { + if (exp is constant_node) + { + possible_type_convertions pct = type_table.get_convertions(exp.type, tn); + if (pct.first != null && pct.first.convertion_method.IsOperator) + //if (convertion_data_and_alghoritms.can_convert_type(exp, tn)) + return convertion_data_and_alghoritms.convert_type(exp, tn); + else return convert_strong_to_constant_node(exp, tn); + } + if (exp is array_initializer) + { + //if (tn.type_special_kind != SemanticTree.type_special_kind.array_wrapper) + { + //exp.type = DeduceType(exp.type,exp.location); + exp = ConvertArrayInitializer(tn, exp as array_initializer); + return exp; + //return convertion_data_and_alghoritms.convert_type(exp,tn); + } +// else +// { +// exp.type = tn; +// return exp; +// } + } + else if (exp is compiled_static_method_call && (exp.type.type_special_kind == SemanticTree.type_special_kind.set_type || exp.type.type_special_kind == SemanticTree.type_special_kind.base_set_type)) + { + if (!(tn == exp.type) && !type_table.is_derived(tn, exp.type) && !(convertion_data_and_alghoritms.can_convert_type(exp, tn))) + { + AddError(new CanNotConvertTypes(exp, exp.type, tn, exp.location)); + } + if (tn.element_type != null) + { + ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; + if (oti != null) + { + compiled_static_method_call cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as compiled_function_node, null); + cmc.parameters.AddElement(exp); + cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); + cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); + cmc.ret_type = tn; + return new compiled_static_method_call_as_constant(cmc, null); + } + else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) + { + compiled_static_method_call cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as compiled_function_node, null); + cmc.parameters.AddElement(exp); + cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length, null)); + cmc.ret_type = tn; + return new compiled_static_method_call_as_constant(cmc, null); + } + } + return new compiled_static_method_call_as_constant(exp as compiled_static_method_call, null); + } + else if (exp is common_namespace_function_call && (exp.type.type_special_kind == SemanticTree.type_special_kind.set_type || exp.type.type_special_kind == SemanticTree.type_special_kind.base_set_type)) + { + if (!(tn == exp.type) && !type_table.is_derived(tn, exp.type) && !(convertion_data_and_alghoritms.can_convert_type(exp, tn))) + { + AddError(new CanNotConvertTypes(exp, exp.type, tn, exp.location)); + } + if (tn.element_type != null) + { + ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; + if (oti != null) + { + common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node, null); + cmc.parameters.AddElement(exp); + cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); + cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); + cmc.ret_type = tn; + return new common_namespace_function_call_as_constant(cmc, null); + } + else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) + { + common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node, null); + cmc.parameters.AddElement(exp); + cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length, null)); + cmc.ret_type = tn; + return new common_namespace_function_call_as_constant(cmc, null); + } + } + return new common_namespace_function_call_as_constant(exp as common_namespace_function_call, null); + } + else if (exp is record_initializer) + { + if (tn is common_type_node) + exp = ConvertRecordInitializer(tn as common_type_node, exp as record_initializer); + else if (tn is compiled_type_node) + throw new NotSupportedError(exp.location); + return exp; + } + switch (SemanticRules.VariableInitializationParams) + { + case VariableInitializationParams.ConstructorCall: + if ((exp is common_constructor_call) || (exp is compiled_constructor_call)) + return convertion_data_and_alghoritms.convert_type(exp, tn); + break; + case VariableInitializationParams.Expression: + if (exp.type != null) + return convertion_data_and_alghoritms.convert_type(exp, tn); + break; + } + return convert_strong_to_constant_node(exp, tn); + } + + private constant_node convert_strong_to_constant_node(SyntaxTree.expression expr, type_node tn) + { + var exp = convert_strong(expr); + var is_const_section = (expr.Parent != null && (expr.Parent is const_definition)); + + var is_userdefined = false; + var cnf = exp as common_namespace_function_call; + if (cnf != null) + { + is_userdefined = !(cnf.function_node.namespace_node.namespace_name.Equals("PABCSystem") || cnf.function_node.namespace_node.namespace_name.Equals("PABCSystem_implementation______")); + } + + return convert_strong_to_constant_node(exp, tn, is_const_section && is_userdefined, is_const_section); + } + + private void check_set_for_constant(common_namespace_function_call cnfc) + { + expressions_list exprs = null; + if (cnfc.function_node == SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node) + exprs = get_set_initializer(cnfc); + else exprs = cnfc.parameters; + foreach (expression_node en in exprs) + if (en is common_namespace_function_call) + { + cnfc = en as common_namespace_function_call; + if (cnfc.function_node == PascalABCCompiler.SystemLibrary.SystemLibInitializer.SetUnionProcedure.sym_info as common_namespace_function_node + || cnfc.function_node == PascalABCCompiler.SystemLibrary.SystemLibInitializer.SetSubtractProcedure.sym_info as common_namespace_function_node + || cnfc.function_node == PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node + || cnfc.function_node == PascalABCCompiler.SystemLibrary.SystemLibInitializer.SetIntersectProcedure.sym_info as common_namespace_function_node + || cnfc.function_node == PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateDiapason.sym_info as common_namespace_function_node + || cnfc.function_node == PascalABCCompiler.SystemLibrary.SystemLibInitializer.CreateObjDiapason.sym_info as common_namespace_function_node) + check_set_for_constant(en as common_namespace_function_call); + else AddError(en.location, "CONSTANT_EXPRESSION_EXPECTED"); + } + else + if (!(en is constant_node /*|| en is statements_expression_node*/)) AddError(en.location, "CONSTANT_EXPRESSION_EXPECTED"); + } + + private constant_node convert_strong_to_constant_node(expression_node expr, type_node tn, bool is_const_section_and_userfuncall = false, bool is_const_section = false, location parent_loc = null) + { + location loc = expr.location; + if (parent_loc != null) + loc = parent_loc; + constant_node constant = null; + try_convert_typed_expression_to_function_call(ref expr); + if (expr is null_const_node) + { + if (!(tn is null_type_node) && !type_table.is_with_nil_allowed(tn)) + AddError(loc, "NIL_WITH_VALUE_TYPES_NOT_ALLOWED"); + return null_const_node.get_const_node_with_type(tn, expr as null_const_node); + } + if (expr is compiled_static_method_call) + { + compiled_static_method_call csmc = expr as compiled_static_method_call; + + if (csmc.type != null && csmc.type != SystemLibrary.SystemLibrary.void_type && (csmc.function_node.IsSpecialName && csmc.function_node.is_readonly || NetHelper.NetHelper.PABCSystemType != null && csmc.function_node.cont_type.compiled_type.Assembly == NetHelper.NetHelper.PABCSystemType.Assembly || !is_const_section)) + constant = new compiled_static_method_call_as_constant(csmc, expr.location); + } + else if (expr is common_namespace_function_call && SystemLibrary.SystemLibInitializer.CreateSetProcedure != null && (expr as common_namespace_function_call).function_node == SystemLibrary.SystemLibInitializer.CreateSetProcedure.sym_info as common_namespace_function_node) + { + common_namespace_function_call cnfc = expr as common_namespace_function_call; + expressions_list exprs = get_set_initializer(cnfc); + check_set_for_constant(cnfc); + foreach (expression_node en in exprs) + { + if (en is common_namespace_function_call) + { + common_namespace_function_call cnfc2 = en as common_namespace_function_call; + check_set_for_constant(cnfc2); + } + else + if (!(en is constant_node)) AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); + } + constant = new common_namespace_function_call_as_constant(cnfc, loc); + } + else if (is_const_section_and_userfuncall && (expr is basic_function_call || expr is common_namespace_function_call)) // только в разделе const + { + AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); + } + else if (expr is common_namespace_function_call) + { + common_namespace_function_call cnfc=expr as common_namespace_function_call; + foreach (expression_node el in cnfc.parameters) + convert_strong_to_constant_node(el, el.type, false, false, cnfc.location); + //if (cnfc.function_node.namespace_node == context.converted_namespace) + // AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); + // throw new ConstantExpressionExpected(loc); + constant = new common_namespace_function_call_as_constant(expr as common_namespace_function_call, loc); + } + else if (expr is basic_function_call) + { + basic_function_call cnfc=expr as basic_function_call; + //if (cnfc.function_node.namespace_node == context.converted_namespace) + // throw new ConstantExpressionExpected(loc); + foreach (expression_node el in cnfc.parameters) + convert_strong_to_constant_node(el, el.type); + constant = new basic_function_call_as_constant(expr as basic_function_call, loc); + } + else if (expr is typed_expression) + { + expr = convertion_data_and_alghoritms.convert_type(expr, tn); + if (expr is common_constructor_call) + { + constant = new common_constructor_call_as_constant(expr as common_constructor_call, null); + } + else + if (expr is typed_expression) + { + if (const_def_type != null) + { + expr = convertion_data_and_alghoritms.convert_type(expr, const_def_type); + tn = const_def_type; + constant = new common_constructor_call_as_constant(expr as common_constructor_call, null); + } + else + { + base_function_call bfc = ((expr as typed_expression).type as delegated_methods).proper_methods[0]; + common_type_node del = + convertion_data_and_alghoritms.type_constructor.create_delegate(context.get_delegate_type_name(), bfc.simple_function_node.return_value_type, bfc.simple_function_node.parameters, context.converted_namespace, null); + context.converted_namespace.types.AddElement(del); + tn = del; + expr = convertion_data_and_alghoritms.explicit_convert_type(expr, del); + expr.type = tn; + constant = new common_constructor_call_as_constant(expr as common_constructor_call, loc); + } + } + } + + else if (expr is namespace_constant_reference) + { + constant = (expr as namespace_constant_reference).constant.const_value; + convertion_data_and_alghoritms.check_convert_type(constant,tn,expr.location); + if ((tn.type_special_kind == SemanticTree.type_special_kind.set_type || tn.type_special_kind == SemanticTree.type_special_kind.base_set_type) && tn.element_type != null) + { + ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; + if (oti != null) + { + common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node,null); + cmc.parameters.AddElement(expr); + cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); + cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); + cmc.ret_type = tn; + constant = new common_namespace_function_call_as_constant(cmc,null); + } + else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) + { + common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node,null); + cmc.parameters.AddElement(expr); + cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length,null)); + cmc.ret_type = tn; + constant = new common_namespace_function_call_as_constant(cmc,null); + } + } + else + if (tn.type_special_kind == SemanticTree.type_special_kind.short_string) + { + /*common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node,null); + cmc.parameters.AddElement(expr); + cmc.parameters.AddElement(new int_const_node((tn as short_string_type_node).Length,null));*/ + expression_node cmc = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(expr,SystemLibrary.SystemLibrary.string_type),new int_const_node((tn as short_string_type_node).Length,null)); + constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call,null); + } + /*expression_node e = convertion_data_and_alghoritms.convert_type(constant.get_constant_copy(expr.location), tn); + switch (e.semantic_node_type) + { + case semantic_node_type.compiled_constructor_call: + constant = new compiled_constructor_call_as_constant(e as compiled_constructor_call, loc); + break; + default: + constant = e as constant_node; + break; + }*/ + /*if (constant.get_object_value() != null) + { + //if (const_def_type != null) + { + expression_node e = convertion_data_and_alghoritms.convert_type(constant.get_constant_copy(expr.location), tn); + switch (e.semantic_node_type) + { + case semantic_node_type.compiled_constructor_call: + constant = new compiled_constructor_call_as_constant(e as compiled_constructor_call, loc); + break; + default: + constant = e as constant_node; + break; + } + } + } + else + { + //if (const_def_type != null) + { + expression_node e = convertion_data_and_alghoritms.convert_type(expr, tn); + switch (e.semantic_node_type) + { + case semantic_node_type.compiled_constructor_call: + constant = new compiled_constructor_call_as_constant(e as compiled_constructor_call, loc); + break; + default: + constant = e as constant_node; + break; + } + } + }*/ + return constant; + } + else if (expr is function_constant_reference) + { + constant = (expr as function_constant_reference).constant.const_value; + convertion_data_and_alghoritms.check_convert_type(constant,tn,expr.location); + if ((tn.type_special_kind == SemanticTree.type_special_kind.set_type || tn.type_special_kind == SemanticTree.type_special_kind.base_set_type) && tn.element_type != null) + { + ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; + if (oti != null) + { + common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node,null); + cmc.parameters.AddElement(expr); + cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); + cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); + cmc.ret_type = tn; + constant = new common_namespace_function_call_as_constant(cmc,null); + } + else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) + { + common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node,null); + cmc.parameters.AddElement(expr); + cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length,null)); + cmc.ret_type = tn; + constant = new common_namespace_function_call_as_constant(cmc,null); + } + } + else + if (tn.type_special_kind == SemanticTree.type_special_kind.short_string) + { + /*common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node,null); + cmc.parameters.AddElement(expr); + cmc.parameters.AddElement(new int_const_node((tn as short_string_type_node).Length,null));*/ + expression_node cmc = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(expr,SystemLibrary.SystemLibrary.string_type),new int_const_node((tn as short_string_type_node).Length,null)); + constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call,null); + } + return constant; + } + else if (expr is static_compiled_variable_reference && !(expr as static_compiled_variable_reference).var.IsLiteral) + { + constant = new compiled_static_field_reference_as_constant(expr as static_compiled_variable_reference, null); + return constant; + } + else if (expr is default_operator_node) + constant = new default_operator_node_as_constant(expr as default_operator_node, null); + else + { + constant = expr as constant_node; + if (tn.type_special_kind == SemanticTree.type_special_kind.short_string) + { + /*common_namespace_function_call cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as common_namespace_function_node,null); + cmc.parameters.AddElement(expr); + cmc.parameters.AddElement(new int_const_node((tn as short_string_type_node).Length,null));*/ + expression_node cmc = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node, null, convertion_data_and_alghoritms.convert_type(expr, SystemLibrary.SystemLibrary.string_type), new int_const_node((tn as short_string_type_node).Length, null)); + if (cmc is common_namespace_function_call) + constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call, null); + else + constant = new compiled_static_method_call_as_constant(cmc as compiled_static_method_call, null); + } + //else + //constant = convertion_data_and_alghoritms.convert_type(constant, tn) as constant_node; + if (expr is static_compiled_variable_reference) + { + compiled_class_constant_definition cccd = NetHelper.NetHelper.ConvertToConstant(((static_compiled_variable_reference)expr).var); + if (cccd != null) + constant = cccd.const_value; + else + constant = new compiled_static_field_reference_as_constant(expr as static_compiled_variable_reference, null); + } + + } + + if (constant == null) + AddError(loc, "CONSTANT_EXPRESSION_EXPECTED"); + if (IsBoundedArray(tn) || IsUnsizedArray(tn)) + { + if (!(constant is array_const)) + AddError(loc, "ARRAY_CONST_EXPECTED"); + constant = ConvertArrayConst(tn, constant as array_const); + } + else + if (tn is common_type_node) + { + if (tn.type_special_kind != SemanticTree.type_special_kind.set_type && tn.type_special_kind != SemanticTree.type_special_kind.base_set_type && tn.type_special_kind != SemanticTree.type_special_kind.diap_type) + { + if (!tn.is_value) + { + if (expr is common_constructor_call) + return constant; + if (expr is common_constructor_call_as_constant) + return expr as common_constructor_call_as_constant; + convertion_data_and_alghoritms.check_convert_type(expr,tn,expr.location); + return constant; + //AddError(new CanNotConvertTypes(expr,expr.type,tn,expr.location)); + //throw new NotSupportedError(loc); + } + if ((tn as common_type_node).IsEnum) + { + convertion_data_and_alghoritms.check_convert_type(expr,tn,expr.location); + enum_const_node ecn = expr as enum_const_node; + if (ecn == null) AddError(expr.location, "CONSTANT_EXPRESSION_EXPECTED"); + return ecn; + } + if (!(constant is record_constant)) + AddError(loc, "RECORD_CONST_EXPECTED"); + constant = ConvertRecordConst(tn as common_type_node, constant as record_constant); + } + else if (tn.type_special_kind == SemanticTree.type_special_kind.diap_type) + { + constant = expr as constant_node; + if (constant == null) + AddError(expr.location, "CONSTANT_EXPRESSION_EXPECTED"); + //constant = (expr as namespace_constant_reference).constant.const_value; + convertion_data_and_alghoritms.check_convert_type(constant,tn,expr.location); + ordinal_type_interface oti = tn.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; + bool success = false; + int val = convertion_data_and_alghoritms.convert_type_to_int_constant(constant, out success); + if (success) + { + int left = convertion_data_and_alghoritms.convert_type_to_int_constant(oti.lower_value, out success); + if (success) + { + int right = convertion_data_and_alghoritms.convert_type_to_int_constant(oti.upper_value, out success); + if (success) + if (val < left || val > right) + AddError(loc, "OUT_OF_RANGE"); + } + } + } + else + { + //obrezka konstantnogo mnozhestva + if (!(tn == expr.type) && !type_table.is_derived(tn,expr.type)) + { + AddError(new CanNotConvertTypes(expr,expr.type,tn,expr.location)); + } + if (tn.element_type != null) + { + ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; + if (oti != null) + { + base_function_call cmc = null; + if (SystemLibrary.SystemLibInitializer.ClipFunction.sym_info is common_namespace_function_node) + cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node, null); + else + cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as compiled_function_node, null); + cmc.parameters.AddElement(expr); + cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); + cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); + cmc.ret_type = tn; + if (cmc is common_namespace_function_call) + constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call, null); + else + constant = new compiled_static_method_call_as_constant(cmc as compiled_static_method_call, null); + } + else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) + { + base_function_call cmc = null; + if (SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info is common_namespace_function_node) + cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node, null); + else + cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as compiled_function_node, null); + cmc.parameters.AddElement(expr); + cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length,null)); + cmc.ret_type = tn; + if (cmc is common_namespace_function_call) + constant = new common_namespace_function_call_as_constant(cmc as common_namespace_function_call, null); + else + constant = new compiled_static_method_call_as_constant(cmc as compiled_static_method_call, null); + } + } + } + } + else + { + expression_node exprc = convertion_data_and_alghoritms.convert_type(constant, tn); + switch (exprc.semantic_node_type) + { + case semantic_node_type.compiled_constructor_call: + constant = new compiled_constructor_call_as_constant(exprc as compiled_constructor_call, loc); + break; + case semantic_node_type.compiled_static_method_call: + constant = new compiled_static_method_call_as_constant(exprc as compiled_static_method_call, loc); + break; + case semantic_node_type.basic_function_call: + constant = new basic_function_call_as_constant(exprc as basic_function_call, loc); + break; + case semantic_node_type.common_namespace_function_call: + constant = new common_namespace_function_call_as_constant(exprc as common_namespace_function_call, loc); + break; + default: + constant = exprc as constant_node; + break; + } + } + return constant; + } + + internal common_type_node CreateDelegate(function_node fn) + { + common_type_node del = + convertion_data_and_alghoritms.type_constructor.create_delegate(context.get_delegate_type_name(), fn.return_value_type, fn.parameters, context.converted_namespace, null); + context.converted_namespace.types.AddElement(del); + return del; + } + + internal expression_node CreateDelegateCall(base_function_call fn_call) + { + common_type_node del = CreateDelegate(fn_call.simple_function_node); + common_constructor_call deleg_costructor_call = new common_constructor_call(del.methods[0], fn_call.location); + deleg_costructor_call.parameters.AddElement((base_function_call)fn_call); + return deleg_costructor_call; + } + + private record_initializer ConvertRecordInitializer(common_type_node ctn, record_initializer constant) + { + location loc = constant.location; + if (!ctn.is_value_type) + AddError(loc, "RECORD_CONST_NOT_ALLOWED_{0}", ctn.name); + if (ctn.fields.Count != constant.record_const_definition_list.Count) + AddError(loc, "INVALID_RECORD_CONST_FIELD_COUNT"); + constant.type = ctn; + constant.field_values.Clear(); + for (int i = 0; i < ctn.fields.Count; i++) + { + class_field cf = ctn.fields[i]; + if (cf.name.ToLower() != constant.record_const_definition_list[i].name.name.ToLower()) + AddError(get_location(constant.record_const_definition_list[i].name), "FIELD_NAME_SHOULD_BE_EQUAL_RECORD_FIELD_NAME", cf.name); + expression_node en = convert_strong_to_constant_or_function_call_for_varinit(convert_strong(constant.record_const_definition_list[i].val),cf.type); + en.type = cf.type; + constant.field_values.Add(en); + } + return constant; + } + + private array_initializer ConvertNDimArrayInitializer(type_node tn, int cur_rank, type_node element_type, array_initializer constant) + { + array_internal_interface aii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface; + int rank = aii.rank; + int size = -1; + for (int i=0; i= rank) + constant.element_values[i] = ConvertArrayInitializer(tn.element_type, e as array_initializer); + //AddError(new CanNotConvertTypes(e,e.type,tn.element_type,e.location)); + else + constant.element_values[i] = ConvertNDimArrayInitializer(tn,cur_rank + 1, element_type, e as array_initializer); + } + else if (e is record_initializer) + { + if (element_type is common_type_node) + constant.element_values[i] = ConvertRecordInitializer(element_type as common_type_node, e as record_initializer); + else throw new NotSupportedError(constant.element_values[i].location); + } + else + { + if (cur_rank != rank) + AddError(constant.location, "RANK_MISMATCH_IN_INITILIALIZER"); + constant.element_values[i] = convertion_data_and_alghoritms.convert_type(constant.element_values[i], element_type); + } + } + constant.type = tn; + return constant; + } + + private expression_node ConvertArrayInitializer(type_node tn, array_initializer constant) + { + type_node element_type = null; + if (IsBoundedArray(tn)) + { + bounded_array_interface bai = tn.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface; + element_type = bai.element_type; + ordinal_type_interface oti_indexer = bai.ordinal_type_interface; + int arr_length = oti_indexer.ordinal_type_to_int(oti_indexer.upper_value) - oti_indexer.ordinal_type_to_int(oti_indexer.lower_value) + 1; + if (arr_length != constant.element_values.Count) + AddError(constant.location, "ARRAY_CONST_{0}_ELEMENTS_EXPECTED", arr_length); + } + else + if (IsUnsizedArray(tn)) + { + array_internal_interface aii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface; + element_type = aii.element_type; + if (aii.rank > 1) + { + array_initializer cnst = ConvertNDimArrayInitializer(tn,1,element_type,constant); + cnst.type = tn; + return cnst; + } + } + else if (tn == SystemLibrary.SystemLibrary.complex_type && constant.element_values.Count == 2) + { + compiled_constructor_call cccall = new compiled_constructor_call(SystemLibrary.SystemLibrary.complex_type_constructor, null); + cccall.parameters.AddElement(convertion_data_and_alghoritms.convert_type(constant.element_values[0], SystemLibrary.SystemLibrary.double_type)); + cccall.parameters.AddElement(convertion_data_and_alghoritms.convert_type(constant.element_values[1], SystemLibrary.SystemLibrary.double_type)); + compiled_constructor_call_as_constant cccall_cnst = new compiled_constructor_call_as_constant(cccall, null); + return cccall_cnst; + } + else + AddError(new CanNotConvertTypes(constant,constant.type,tn,constant.location));//CompilerInternalError("Unexpected array type"); + for (int i = 0; i < constant.element_values.Count; i++) + if (constant.element_values[i] is array_initializer) + constant.element_values[i] = ConvertArrayInitializer(element_type, constant.element_values[i] as array_initializer); + else if (constant.element_values[i] is record_initializer) + { + if (element_type is common_type_node) + constant.element_values[i] = ConvertRecordInitializer(element_type as common_type_node, constant.element_values[i] as record_initializer); + else throw new NotSupportedError(constant.element_values[i].location); + } + else + { + constant.element_values[i] = convertion_data_and_alghoritms.convert_type(constant.element_values[i], element_type); + } + constant.type = tn; + return constant; + } + + private array_const ConvertNDimArrayConst(type_node tn, int cur_rank, type_node element_type, array_const constant) + { + array_internal_interface aii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface; + int rank = aii.rank; + int size = -1; + for (int i=0; i=rank) + constant.element_values[i] = ConvertArrayConst(tn.element_type,e as array_const); + //AddError(new CanNotConvertTypes(e,e.type,tn.element_type,e.location)); + else + constant.element_values[i] = ConvertNDimArrayConst(tn,cur_rank+1,element_type,e as array_const); + } + else if (e is record_constant) + { + if (element_type is common_type_node) + constant.element_values[i] = ConvertRecordConst(element_type as common_type_node, e as record_constant); + else AddError(new NotSupportedError(constant.element_values[i].location)); + } + else + { + if (cur_rank != rank) + AddError(constant.location, "RANK_MISMATCH_IN_INITILIALIZER"); + constant.element_values[i] = convert_strong_to_constant_node(constant.element_values[i], element_type); + } + } + constant.SetType(tn); + return constant; + } + + private array_const ConvertArrayConst(type_node tn, array_const constant) + { + type_node element_type = null; + if (IsBoundedArray(tn)) + { + bounded_array_interface bai = tn.get_internal_interface(internal_interface_kind.bounded_array_interface) as bounded_array_interface; + element_type = bai.element_type; + ordinal_type_interface oti_indexer = bai.ordinal_type_interface; + int arr_length = oti_indexer.ordinal_type_to_int(oti_indexer.upper_value) - oti_indexer.ordinal_type_to_int(oti_indexer.lower_value) + 1; + if (arr_length != constant.element_values.Count) + AddError(constant.location, "ARRAY_CONST_{0}_ELEMENTS_EXPECTED", arr_length); + } + else + if (IsUnsizedArray(tn)) + { + array_internal_interface aii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface; + element_type = aii.element_type; + if (aii.rank > 1) + { + array_const cnst = ConvertNDimArrayConst(tn,1,element_type,constant); + cnst.SetType(tn); + return cnst; + } + } + else + throw new CompilerInternalError("Unexpected array type"); + for (int i = 0; i < constant.element_values.Count; i++) + constant.element_values[i] = convert_strong_to_constant_node(constant.element_values[i], element_type); + constant.SetType(tn); + return constant; + } + + private record_constant ConvertRecordConst(common_type_node ctn, record_constant constant) + { + location loc = constant.location; + if (!ctn.is_value_type) + AddError(loc, "RECORD_CONST_NOT_ALLOWED_{0}", ctn.name); + if (ctn.fields.Count != constant.record_const_definition_list.Count) + AddError(loc, "INVALID_RECORD_CONST_FIELD_COUNT"); + constant.SetType(ctn); + constant.field_values.Clear(); + bool tmp = this.is_typed_const_def; + this.is_typed_const_def = true; + for (int i = 0; i < ctn.fields.Count; i++) + { + class_field cf = ctn.fields[i]; + if (cf.name.ToLower() != constant.record_const_definition_list[i].name.name.ToLower()) + AddError(get_location(constant.record_const_definition_list[i].name), "FIELD_NAME_SHOULD_BE_EQUAL_RECORD_FIELD_NAME", cf.name); + constant.field_values.Add(convert_strong_to_constant_node(constant.record_const_definition_list[i].val, cf.type)); + } + this.is_typed_const_def = tmp; + return constant; + } + + public override void visit(SyntaxTree.diapason _diapason) + { + constant_node cnleft = convert_strong_to_constant_node(_diapason.left); + constant_node cnright = convert_strong_to_constant_node(_diapason.right); + type_node tn = convertion_data_and_alghoritms.type_constructor.get_pascal_diap(cnleft, cnright, get_location(_diapason.left), + context.converted_namespace, get_location(_diapason.right)); + return_value(tn); + } + + public override void visit(SyntaxTree.ref_type _ref_type) + { + if (_ref_type.pointed_to is SyntaxTree.named_type_reference && + ((_ref_type.pointed_to as SyntaxTree.named_type_reference).names.Count == 1) && + context.CurrentScope.Find((_ref_type.pointed_to as SyntaxTree.named_type_reference).names[0].name) == null) + { + //это указатель на тип который еще не описан + if (!is_direct_type_decl) + AddError(new UndefinedNameReference((_ref_type.pointed_to as SyntaxTree.named_type_reference).names[0].name,get_location(_ref_type.pointed_to))); + return_value(GetWaitedRefType((_ref_type.pointed_to as SyntaxTree.named_type_reference).names[0].name, get_location(_ref_type.pointed_to))); + } + else + { + type_node tn = convert_strong(_ref_type.pointed_to); + if (tn.is_generic_parameter) + { + if (SemanticRules.AllowPointersForGenericParameters) + { + get_type_abilities(tn).useful_for_pointers = true; + } + else + { + AddError(get_location(_ref_type), "POINTERS_OF_GENERIC_PARAMETERS_NOT_ALLOWED"); + } + } + else + { + if (!tn.is_value /*&& tn.type_special_kind != SemanticTree.type_special_kind.array_kind && tn.type_special_kind != SemanticTree.type_special_kind.set_type && tn.type_special_kind != SemanticTree.type_special_kind.array_wrapper && tn.type_special_kind != SemanticTree.type_special_kind.binary_file + && tn.type_special_kind != SemanticTree.type_special_kind.binary_file*/ && !(tn is ref_type_node) && tn != SystemLibrary.SystemLibrary.pointer_type && tn.type_special_kind != SemanticTree.type_special_kind.short_string && tn.type_special_kind != SemanticTree.type_special_kind.diap_type && !tn.IsEnum && + !(tn.semantic_node_type == semantic_node_type.indefinite_type)) + AddError(get_location(_ref_type), "POINTERS_OF_REF_TYPES_NOT_ALLOWED"); + } + ref_type_node rtn = tn.ref_type; + if (rtn != null) + { + rtn.loc = get_location(_ref_type); + if (SemanticRules.StrongPointersTypeCheckForDotNet) + //CheckPointersTypeForDotNetFramework(tn, get_location(_ref_type.pointed_to)); + RefTypesForCheckPointersTypeForDotNetFramework.Add(rtn); + return_value(rtn); + } + else + { + return_value(SystemLibrary.SystemLibrary.pointer_type); + } + } + } + + internal bool CheckPointersTypeForDotNetFramework(type_node tn, location loc) + { + type_node ttn = FindBadTypeNodeForPointersInDotNetFramework(tn); + __findBadTypeNodeForPointersPreparedTypes.Clear(); + if (ttn != null) + { + AddErrorCheckPointersTypeForDotNetFramework(tn, ttn, loc); + return false; + } + return true; + } + + public void AddErrorCheckPointersTypeForDotNetFramework(type_node tn, type_node ttn, location loc) + { + if (tn == ttn) + AddError(loc, "CANNOT_DECLARED_POINTER_TO_REFERENCE_TYPE"); + else + AddError(loc, "CANNOT_DECLARED_POINTER_TO_RECORD_CONTAINS_REFERENCE_FIELDS"); + } + private List __findBadTypeNodeForPointersPreparedTypes = new List(); + private type_node FindBadTypeNodeForPointersInDotNetFramework(type_node tn) + { + if (__findBadTypeNodeForPointersPreparedTypes.Contains(tn)) + return null; + __findBadTypeNodeForPointersPreparedTypes.Add(tn); + if (tn.semantic_node_type == semantic_node_type.indefinite_type) + { + return null; + } + if (tn.is_generic_parameter) + { + if (SemanticRules.AllowPointersForGenericParameters) + { + get_type_abilities(tn).useful_for_pointers = true; + return null; + } + else + { + return tn; + } + } + type_node btn = null; + if (tn is ref_type_node) + return FindBadTypeNodeForPointersInDotNetFramework((tn as ref_type_node).pointed_type); + if (tn == SystemLibrary.SystemLibrary.pointer_type || tn == SystemLibrary.SystemLibrary.void_type) + return null; + if (tn.is_value) + { + generic_instance_type_node gitn = tn as generic_instance_type_node; + if (gitn != null) + { + List ftypes = gitn.all_field_types; + foreach (type_node ftype in ftypes) + { + if ((btn = FindBadTypeNodeForPointersInDotNetFramework(ftype)) != null) + return btn; + } + return null; + } + if (tn is common_type_node) + { + if (tn.IsEnum || tn.type_special_kind == SemanticTree.type_special_kind.diap_type) return null; + common_type_node ctn = tn as common_type_node; + foreach (class_field cf in ctn.fields) + if (!cf.IsStatic) + if ((btn = FindBadTypeNodeForPointersInDotNetFramework(cf.type)) != null) + return btn; + return null; + } + if (tn is compiled_type_node) + { + compiled_type_node ctn = tn as compiled_type_node; + if (ctn.IsPrimitive) + return null; + System.Reflection.FieldInfo[] fields = ctn.compiled_type.GetFields(); + foreach (System.Reflection.FieldInfo fi in fields) + if (!fi.IsStatic) + if ((btn = FindBadTypeNodeForPointersInDotNetFramework(compiled_type_node.get_type_node(fi.FieldType))) != null) + return btn; + return null; + } + } + /*if (IsBoudedArray(el_type)) + { + //это обычный массив + bounded_array_interface bai = (bounded_array_interface)el_type.get_internal_interface(internal_interface_kind.bounded_array_interface); + return CanUseThisTypeForTypedFiles(bai.element_type); + }*/ + if (tn == SystemLibrary.SystemLibrary.string_type || tn.type_special_kind == SemanticTree.type_special_kind.set_type || tn.type_special_kind == SemanticTree.type_special_kind.short_string || tn.type_special_kind == SemanticTree.type_special_kind.array_wrapper + || tn.type_special_kind == SemanticTree.type_special_kind.typed_file || tn.type_special_kind == SemanticTree.type_special_kind.binary_file || tn.type_special_kind == SemanticTree.type_special_kind.text_file + || tn.type_special_kind == SemanticTree.type_special_kind.array_kind) return null; + return tn; + } + + + /*private void ConvertStatement(SyntaxTree.statement stmt) + { + while (stmt != null) + { + if (stmt is SyntaxTree.if_node) + { + SyntaxTree.if_node _if_node = stmt as SyntaxTree.if_node; + + expression_node condition = convert_strong(_if_node.condition); + condition = convertion_data_and_alghoritms.convert_type(condition, SystemLibrary.SystemLibrary.bool_type); + + statements_list sl = new statements_list(get_location(_if_node.then_body)); + convertion_data_and_alghoritms.statement_list_stack_push(sl); + + context.enter_code_block_with_bind(); + statement_node then_st = convert_strong(_if_node.then_body); + context.leave_code_block(); + + sl = convertion_data_and_alghoritms.statement_list_stack.pop(); + if (sl.statements.Count > 0) + { + sl.statements.AddElement(then_st); + then_st = sl; + } + + if (_if_node.else_body != null) + { + sl = new statements_list(get_location(_if_node.else_body)); + convertion_data_and_alghoritms.statement_list_stack_push(sl); + } + + context.enter_code_block_with_bind(); + statement_node else_st = convert_weak(_if_node.else_body); + context.leave_code_block(); + + if (_if_node.else_body != null) + { + sl = convertion_data_and_alghoritms.statement_list_stack.pop(); + if (sl.statements.Count > 0) + { + sl.statements.AddElement(else_st); + else_st = sl; + } + } + + if_node if_node = new if_node(condition, then_st, else_st, get_location(_if_node)); + return_value(if_node); + return; + } + visit(stmt); + } + }*/ + + void CheckToEmbeddedStatementCannotBeADeclaration(SyntaxTree.statement st) + { + if (st != null && st is SyntaxTree.var_statement) + AddError(get_location(st), "EMBEDDED_SATATEMENT_CANNOT_BE_A_DECLARATION"); + } + + public override void visit(SyntaxTree.if_node _if_node) + { + expression_node condition = convert_strong(_if_node.condition); + condition = convertion_data_and_alghoritms.convert_type(condition, SystemLibrary.SystemLibrary.bool_type); + + // SSM 29/08/16 + /*var cc = condition as bool_const_node; + if (cc != null && cc.constant_value == false && _if_node.else_body == null) + { + // недостижимый код - ничего не генерировать + return_value(new empty_statement(get_location(_if_node))); + // перед этим надо обходить then_body + return; + }*/ + + CheckToEmbeddedStatementCannotBeADeclaration(_if_node.then_body); + CheckToEmbeddedStatementCannotBeADeclaration(_if_node.else_body); + + statements_list sl = new statements_list(get_location(_if_node.then_body)); + convertion_data_and_alghoritms.statement_list_stack_push(sl); + + context.enter_code_block_with_bind(); + statement_node then_st = convert_strong(_if_node.then_body); + context.leave_code_block(); + + sl = convertion_data_and_alghoritms.statement_list_stack.pop(); + if (sl.statements.Count > 0 || sl.local_variables.Count > 0) + { + sl.statements.AddElement(then_st); + then_st = sl; + } + + if (_if_node.else_body != null) + { + sl = new statements_list(get_location(_if_node.else_body)); + convertion_data_and_alghoritms.statement_list_stack_push(sl); + } + + context.enter_code_block_with_bind(); + statement_node else_st = convert_weak(_if_node.else_body); + context.leave_code_block(); + + if (_if_node.else_body != null) + { + sl = convertion_data_and_alghoritms.statement_list_stack.pop(); + if (sl.statements.Count > 0 || sl.local_variables.Count > 0) + { + sl.statements.AddElement(else_st); + else_st = sl; + } + } + + if_node if_node = new if_node(condition, then_st, else_st, get_location(_if_node)); + return_value(if_node); + } + + public override void visit(SyntaxTree.while_node _while_node) + { + expression_node expr = convert_strong(_while_node.expr); + expr = convertion_data_and_alghoritms.convert_type(expr, SystemLibrary.SystemLibrary.bool_type); + + CheckToEmbeddedStatementCannotBeADeclaration(_while_node.statements); + + while_node wn = new while_node(expr, get_location(_while_node)); + context.cycle_stack.push(wn); + + statements_list sl = new statements_list(get_location(_while_node.statements)); + convertion_data_and_alghoritms.statement_list_stack_push(sl); + + context.enter_code_block_with_bind(); + statement_node st = convert_strong(_while_node.statements); + context.leave_code_block(); + + sl = convertion_data_and_alghoritms.statement_list_stack.pop(); + if (sl.statements.Count > 0 || sl.local_variables.Count > 0) + { + sl.statements.AddElement(st); + st = sl; + } + + wn.body = st; + context.cycle_stack.pop(); + return_value(wn); + } + + public override void visit(SyntaxTree.repeat_node _repeat_node) + { + repeat_node rep = new repeat_node(get_location(_repeat_node)); + context.cycle_stack.push(rep); + + statements_list sl = new statements_list(get_location(_repeat_node.statements)); + convertion_data_and_alghoritms.statement_list_stack_push(sl); + + CheckToEmbeddedStatementCannotBeADeclaration(_repeat_node.statements); + + statement_node st = convert_strong(_repeat_node.statements); + + sl = convertion_data_and_alghoritms.statement_list_stack.pop(); + //if (!(st is statements_list)) + if (sl.statements.Count > 0 || sl.local_variables.Count > 0) + { + sl.statements.AddElement(st); + st = sl; + } + + rep.body = st; + expression_node expr = convert_strong(_repeat_node.expr); + expr = convertion_data_and_alghoritms.convert_type(expr, SystemLibrary.SystemLibrary.bool_type); + rep.condition = expr; + context.cycle_stack.pop(); + return_value(rep); + } + + + + + private expression_node additional_indexer_convertion(expression_node ind_expr, type_node array_type) + { + return convertion_data_and_alghoritms.convert_type(ind_expr, SystemLibrary.SystemLibrary.integer_type); + } + + private void indexer_as_expression_index(expression_node expr, SyntaxTree.expression_list parameters, + motivation mot, location loc) + { + try_convert_typed_expression_to_function_call(ref expr); + + // SSM 10.01.16 Tuple t[i] + var ent = expr.type as compiled_type_node; + + if (ent== null) + { + var eeee = expr.type as compiled_generic_instance_type_node; + if (eeee!= null) + ent = eeee.original_generic as compiled_type_node; + } + + if (ent != null) + { + var t = ent.compiled_type; + if (t != null && !t.IsArray && t.FullName.StartsWith("System.Tuple")) + { + expression eee = parameters.expressions[0]; + + if (parameters.expressions.Count > 1) + AddError(get_location(eee), "TUPLE_CAN_HAVE_ONLY_ONE_INDEX"); + + var cn = convert_strong_to_constant_node(eee); + + var v = cn as int_const_node; + + if (v != null) + { + if (v.constant_value<0 || v.constant_value >= t.GetGenericArguments().Count()) + AddError(cn.location, "TUPLE_INDEX_OUT_OF_RANGE_{0}", t.GetGenericArguments().Count()-1); + var dn = new dot_node(new semantic_addr_value(expr), new ident("Item" + (v.constant_value + 1).ToString(), eee.source_context),new SourceContext(loc.begin_line_num,loc.begin_column_num,loc.end_line_num,loc.end_column_num)); + visit(dn); + return; + } + else AddError(cn.location, "TUPLE_INDEX_MUST_BE_INTEGER_CONSTANT"); + } + } + // end SSM 09.01.16 Tuple t[i] + + if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_kind) + { + internal_interface ii = expr.type.get_internal_interface(internal_interface_kind.unsized_array_interface); + array_internal_interface aii = (array_internal_interface)ii; + int rank = aii.rank; + //TODO: Многомерные массивы. + expression_node ind_expr = convert_strong(parameters.expressions[0]); + ind_expr = additional_indexer_convertion(ind_expr, expr.type); + simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, aii.element_type, loc); + if (rank == 1) + for (int i = 1; i < parameters.expressions.Count; i++) + { + ii = sai.type.get_internal_interface(internal_interface_kind.unsized_array_interface); + location lloc = get_location(parameters.expressions[i]); + if (ii == null) + { + AddError(lloc, "{0}_DIMENSIONAL_ARRAY_CAN_NOT_HAVE_{1}_AND_MORE_INDEXING", i, i+1); + } + aii = (array_internal_interface)ii; + ind_expr = convert_strong(parameters.expressions[i]); + ind_expr = additional_indexer_convertion(ind_expr, sai.type); + sai = new simple_array_indexing(sai, ind_expr, aii.element_type, lloc); + } + else + { + if (rank != parameters.expressions.Count) + AddError(get_location(parameters), "{0}_DIMENSIONAL_ARRAY_CAN_NOT_HAVE_{1}_AND_MORE_INDEXING", rank, rank + 1); + List lst = new List(); + for (int i = 0; i < parameters.expressions.Count; i++) + { + location lloc = get_location(parameters.expressions[i]); + ind_expr = convert_strong(parameters.expressions[i]); + ind_expr = additional_indexer_convertion(ind_expr, sai.type); + lst.Add(ind_expr); + } + sai = new simple_array_indexing(expr, lst[0], aii.element_type, get_location(parameters)); + sai.expr_indices = lst.ToArray(); + } + switch (mot) + { + case motivation.address_receiving: + { + return_addressed_value(sai); + break; + } + case motivation.expression_evaluation: + { + return_value(sai); + break; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(sai); + break; + } + } + return; + } + else if (expr.type.type_special_kind == SemanticTree.type_special_kind.short_string) + { + if (parameters.expressions.Count != 1) + AddError(loc, "INVALID_PARAMETER_COUNT_IN_INDEXER"); + expression_node ind_expr = convert_strong(parameters.expressions[0]); + ind_expr = additional_indexer_convertion(ind_expr, expr.type); + //expression_node en = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null)); + switch (mot) + { + case motivation.address_receiving: + { + simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, SystemLibrary.SystemLibrary.char_type, loc); + return_addressed_value(sai); + //return_addressed_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.SetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr) as common_namespace_function_call); + break; + } + case motivation.expression_evaluation: + { + return_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null))); + break; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.GetCharInShortStringProcedure.sym_info as function_node,loc,expr,ind_expr,new int_const_node((expr.type as short_string_type_node).Length,null))); + break; + } + } + return; + + } + /*else if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper) + { + internal_interface ii = expr.type.get_internal_interface(internal_interface_kind.bounded_array_interface); + array_internal_interface aii = (array_internal_interface)ii; + //TODO: Многомерные массивы. + expression_node ind_expr = convert_strong(parameters.expressions[0]); + ind_expr = additional_indexer_convertion(ind_expr, expr.type); + simple_array_indexing sai = new simple_array_indexing(expr, ind_expr, aii.element_type, loc); + for (int i = 1; i < parameters.expressions.Count; i++) + { + ii = sai.type.get_internal_interface(internal_interface_kind.bounded_array_interface); + location lloc = get_location(parameters.expressions[i]); + if (ii == null) + { + throw new NDimensionalArrayCanNotHaveNPlusOneIndexer(lloc, expr, i); + } + aii = (array_internal_interface)ii; + ind_expr = convert_strong(parameters.expressions[i]); + ind_expr = create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, ind_expr, + new int_const_node(ii.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),cmc.location)); + ind_expr = additional_indexer_convertion(ind_expr, sai.type); + sai = new simple_array_indexing(sai, ind_expr, aii.element_type, lloc); + } + switch (mot) + { + case motivation.address_reciving: + { + return_addressed_value(sai); + break; + } + case motivation.expression_evaluation: + { + return_value(sai); + break; + } + case motivation.semantic_node_reciving: + { + return_semantic_value(sai); + break; + } + } + return; + + if (factparams[i].semantic_node_type == semantic_node_type.common_method_call) + { + common_method_call cmc = (common_method_call)factparams[i]; + internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); + if (ii != null) + { + if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) + { + bounded_array_interface bai = (bounded_array_interface)ii; + class_field cf = bai.int_array; + expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); + expression_node right = cmc.parameters[0]; + //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); + right = convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); + right = create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, + new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value),cmc.location)); + factparams[i] = new simple_array_indexing(left, right, cmc.type, cmc.location); + is_pascal_array_ref = true; + } + } + } + }*/ + if (expr.type.default_property_node == null) + { + if (expr.type.semantic_node_type != semantic_node_type.delegated_method) + { + AddError(loc, "NO_DEFAULT_PROPERTY_TO_TYPE_{0}", expr.type.PrintableName); + } + else + { + AddError(loc, "NO_DEFAULT_PROPERTY_TO_FUNCTION_TYPE"); + } + } + + if (expr.type.default_property_node.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + AddError(new CanNotReferenceToStaticPropertyWithExpression(expr.type.default_property_node, loc, expr.type)); + } + non_static_property_reference nspr = new non_static_property_reference(expr.type.default_property_node, expr, loc); + indexer_as_property_indexes(nspr, parameters, mot, loc); + //eto vrode rabotaet normalno. no imet v vidu + if (expr.type.type_special_kind == SemanticTree.type_special_kind.array_wrapper) + { + expression_node en = ret.get_expression(); + if (en is non_static_property_reference) + { + non_static_property_reference cmc = (non_static_property_reference)en; + internal_interface ii = cmc.expression.type.get_internal_interface(internal_interface_kind.bounded_array_interface); + if (ii != null) + { + //if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) + { + bounded_array_interface bai = (bounded_array_interface)ii; + class_field cf = bai.int_array; + expression_node left = new class_field_reference(cf, cmc.expression, cmc.location); + expression_node right = cmc.fact_parametres[0]; + //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); + right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); + right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, + new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); + en = new simple_array_indexing(left, right, cmc.type, cmc.location); + //is_pascal_array_ref = true; + } + } + } + else + { + common_method_call cmc = (common_method_call)en; + internal_interface ii = cmc.obj.type.get_internal_interface(internal_interface_kind.bounded_array_interface); + if (ii != null) + { + //if (cmc.function_node.name == compiler_string_consts.get_val_pascal_array_name) + { + bounded_array_interface bai = (bounded_array_interface)ii; + class_field cf = bai.int_array; + expression_node left = new class_field_reference(cf, cmc.obj, cmc.location); + expression_node right = cmc.parameters[0]; + //right = convert_type(right, SystemLibrary.SystemLibrary.integer_type); + right = convertion_data_and_alghoritms.convert_type(right, (ii as bounded_array_interface).ordinal_type_interface.elems_type); + right = convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibrary.int_sub, cmc.location, right, + new int_const_node(bai.ordinal_type_interface.ordinal_type_to_int(bai.ordinal_type_interface.lower_value), cmc.location)); + en = new simple_array_indexing(left, right, cmc.type, cmc.location); + //is_pascal_array_ref = true; + } + } + } + return_value(en); + } + + return; + } + + private void indexer_as_type_indexes(type_node type, SyntaxTree.expression_list parameters, motivation mot, + location loc) + { + if (type.default_property_node == null) + { + if (type.semantic_node_type != semantic_node_type.delegated_method) + { + AddError(loc, "NO_DEFAULT_PROPERTY_TO_TYPE_{0}", type.PrintableName); + } + else + { + AddError(loc, "NO_DEFAULT_PROPERTY_TO_FUNCTION_TYPE"); + } + } + if (type.default_property_node.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + { + AddError(new CanNotReferenceToNonStaticPropertyWithType(type.default_property_node, loc, type)); + } + static_property_reference spr = new static_property_reference(type.default_property_node, loc); + indexer_as_property_indexes(spr, parameters, mot, loc); + return; + } + + private void indexer_as_property_indexes(static_property_reference spr, SyntaxTree.expression_list parameters, + motivation mot, location loc) + { + /*if (spr.property.parameters.Count==0) + { + switch(mot) + { + case motivation.expression_evaluation: + case motivation.semantic_node_reciving: + { + function_node fn=spr.property.get_function; + base_function_call_with_method bfc=convertion_data_and_alghoritms.create_simple_function_call(fn,loc,new expression_node[0]); + return_value(bfc); + return; + } + case motivation.address_reciving: + { + return_addressed_value(spr); + return; + } + } + throw new CompilerInternalError("Unsupported motivation"); + }*/ + if (spr.property.parameters.Count != 0) + { + if (parameters.expressions.Count != spr.property.parameters.Count) + { + AddError(loc, "PROPERTY_{0}_REFERENCE_WITH_INVALID_PARAMS_COUNT", spr.property.name); + } + for (int i = 0; i < parameters.expressions.Count; i++) + { + expression_node exp = convert_strong(parameters.expressions[i]); + exp = convertion_data_and_alghoritms.convert_type(exp, spr.property.parameters[i].type); + spr.fact_parametres.AddElement(exp); + } + } + switch (mot) + { + case motivation.expression_evaluation: + case motivation.semantic_node_reciving: + { + function_node fn = spr.property.get_function; + if (fn == null) + { + AddError(new ThisPropertyCanNotBeReaded(spr.property, loc)); + } + //expression_node bfc=convertion_data_and_alghoritms.create_simple_function_call(fn,loc,spr.fact_params.ToArray()); + base_function_call bfc = create_static_method_call(fn, loc, spr.property.comprehensive_type, false); + bfc.parameters.AddRange(spr.fact_parametres); + if (spr.property.parameters.Count != 0) + { + return_value(bfc); + return; + } + indexer_as_expression_index(bfc, parameters, mot, loc); + return; + } + case motivation.address_receiving: + { + if (spr.property.parameters.Count != 0) + { + return_addressed_value(spr); + return; + } + function_node fn = spr.property.get_function; + if (fn == null) + { + AddError(new ThisPropertyCanNotBeReaded(spr.property, loc)); + } + base_function_call bfc = create_static_method_call(fn, loc, spr.property.comprehensive_type, false); + bfc.parameters.AddRange(spr.fact_parametres); + indexer_as_expression_index(bfc, parameters, mot, loc); + return; + } + } + throw new CompilerInternalError("Unsupported motivation"); + } + + private void indexer_as_property_indexes(non_static_property_reference nspr, SyntaxTree.expression_list parameters, + motivation mot, location loc) + { + if (nspr.property.parameters.Count != 0) + { + if (parameters.expressions.Count != nspr.property.parameters.Count) + { + internal_interface ii = nspr.property.comprehensive_type.get_internal_interface(internal_interface_kind.bounded_array_interface); + if (ii != null) + { + //bounded_array_interface dii = (bounded_array_interface)ii; + + expression_node exp = convert_strong(parameters.expressions[0]); + exp = convertion_data_and_alghoritms.convert_type(exp, nspr.property.parameters[0].type); + nspr.fact_parametres.AddElement(exp); + + base_function_call bfc = null; + + for (int i = 1; i < parameters.expressions.Count; i++) + { + bfc = create_not_static_method_call(nspr.property.get_function, nspr.expression, exp.location, false); + bfc.parameters.AddRange(nspr.fact_parametres); + + location lloc = get_location(parameters.expressions[i]); + ii = bfc.type.get_internal_interface(internal_interface_kind.bounded_array_interface); + if (ii == null) + { + AddError(lloc, "{0}_DIMENSIONAL_ARRAY_CAN_NOT_HAVE_{1}_AND_MORE_INDEXING", i, i+1); + } + bounded_array_interface bii = (bounded_array_interface)ii; + exp = convert_strong(parameters.expressions[i]); + exp = convertion_data_and_alghoritms.convert_type(exp, bii.index_type); + nspr = new non_static_property_reference(bii.index_property, bfc, lloc); + nspr.fact_parametres.AddElement(exp); + } + } + else + { + AddError(loc, "PROPERTY_{0}_REFERENCE_WITH_INVALID_PARAMS_COUNT", nspr.property.name); + } + } + else + { + var lbvr = nspr.expression as local_block_variable_reference; + + //String 1 based + if (parameters.expressions.Count == 1 && + nspr.property.comprehensive_type == SystemLibrary.SystemLibrary.string_type && + !SemanticRules.NullBasedStrings && (lbvr == null || !lbvr.var.name.StartsWith("<>match"))) + { + nspr.fact_parametres.AddElement( + ConstructDecExpr( + convertion_data_and_alghoritms.convert_type( + convert_strong(parameters.expressions[0]), nspr.property.parameters[0].type), null)); + } + else + for (int i = 0; i < parameters.expressions.Count; i++) + { + expression_node exp = convert_strong(parameters.expressions[i]); + exp = convertion_data_and_alghoritms.convert_type(exp, nspr.property.parameters[i].type); + nspr.fact_parametres.AddElement(exp); + } + } + } + switch (mot) + { + case motivation.expression_evaluation: + case motivation.semantic_node_reciving: + { + function_node fn = nspr.property.get_function; + if (fn == null) + { + AddError(new ThisPropertyCanNotBeReaded(nspr.property, loc)); + } + base_function_call bfc = create_not_static_method_call(fn, nspr.expression, loc, false); + bfc.parameters.AddRange(nspr.fact_parametres); + if (nspr.property.parameters.Count != 0) + { + return_value(bfc); + return; + } + indexer_as_expression_index(bfc, parameters, mot, loc); + return; + } + case motivation.address_receiving: + { + if (nspr.property.parameters.Count != 0) + { + return_addressed_value(nspr); + return; + } + function_node fn = nspr.property.get_function; + if (fn == null) + { + AddError(new ThisPropertyCanNotBeReaded(nspr.property, loc)); + } + base_function_call bfc = create_not_static_method_call(fn, nspr.expression, loc, false); + bfc.parameters.AddRange(nspr.fact_parametres); + indexer_as_expression_index(bfc, parameters, mot, loc); + return; + } + } + throw new CompilerInternalError("Unsupported motivation"); + } + + public override void visit(SyntaxTree.indexer _indexer) + { + //SSM 11/02/16 - нет, это глупость + /*if (_indexer.dereferencing_value is SyntaxTree.question_colon_expression) // то разбросать индекс по компонентам + { + var q = _indexer.dereferencing_value as SyntaxTree.question_colon_expression; + var nodeToVisit = new SyntaxTree.question_colon_expression(q.condition, new indexer(q.ret_if_true as addressed_value, _indexer.indexes, _indexer.source_context), + new indexer(q.ret_if_false as addressed_value, _indexer.indexes, _indexer.source_context), _indexer.source_context); + visit(nodeToVisit); + return; + }*/ + //end SSM 11/02/16 + + // SSM 18.08.16 - пробуем обработать захват enn[i] в yieldах где enn - поле класса и нуждается в переименовании + // Так же ниже делает lroman + if (_indexer.dereferencing_value is yield_unknown_ident) + { + var yui = (yield_unknown_ident)_indexer.dereferencing_value; + var av = ProcessUnknownIdent(yui); + var nodeToVisit = new indexer(av,_indexer.indexes); + visit(nodeToVisit); + return; + } + + //lroman + if (_indexer.dereferencing_value is closure_substituting_node) + { + var nodeToVisit = new indexer(((closure_substituting_node) _indexer.dereferencing_value).substitution, + _indexer.indexes); + visit(nodeToVisit); + return; + } + + var mot = motivation_keeper.motivation; + motivation_keeper.reset(); + SyntaxTree.ident idi = _indexer.dereferencing_value as SyntaxTree.ident; + if (idi != null) + { + List sil = context.find(idi.name); + if (sil == null) + { + AddError(new UndefinedNameReference(idi.name, get_location(idi))); + } + if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.type_node) + { + indexer_as_type_indexes((type_node)sil.FirstOrDefault().sym_info, _indexer.indexes, mot, get_location(idi)); + return; + } + if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.property_node) + { + property_node pn = (property_node)sil.FirstOrDefault().sym_info; + if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + static_property_reference spr = new static_property_reference(pn, get_location(idi)); + indexer_as_property_indexes(spr, _indexer.indexes, mot, get_location(idi)); + return; + } + else + { + this_node thisnode = new this_node(pn.comprehensive_type, get_location(_indexer)); + location loc111 = get_location(idi); + non_static_property_reference nspr = new non_static_property_reference(pn, thisnode, loc111); + indexer_as_property_indexes(nspr, _indexer.indexes, mot, loc111); + return; + } + } + expression_node en = ident_value_reciving(sil, idi); + + indexer_as_expression_index(en, _indexer.indexes, mot, get_location(idi)); + return; + } + else + { + SyntaxTree.dot_node dotnd = _indexer.dereferencing_value as SyntaxTree.dot_node; + if (dotnd != null) + { + SyntaxTree.ident id = dotnd.right as SyntaxTree.ident; + semantic_node sn = convert_semantic_strong(dotnd.left); + switch (sn.general_node_type) + { + case general_node_type.type_node: + { + type_node ttp = (type_node)sn; + List sil = ttp.find_in_type(id.name, context.CurrentScope); + if (sil == null) + { + AddError(new UndefinedNameReference(id.name, get_location(id))); + } + if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.property_node) + { + property_node pn = (property_node)sil.FirstOrDefault().sym_info; + static_property_reference spr = new static_property_reference(pn, get_location(id)); + indexer_as_property_indexes(spr, _indexer.indexes, mot, get_location(dotnd)); + return; + } + expression_node exp1 = create_static_expression(ttp, id, sil); + indexer_as_expression_index(exp1, _indexer.indexes, mot, get_location(id)); + return; + } + case general_node_type.namespace_node: + case general_node_type.unit_node: + { + List sil = null; + if (sn is namespace_node) + { + sil = ((namespace_node)sn).find(id.name); + } + else + { + sil = ((unit_node)sn).find_only_in_namespace(id.name); + } + if (sil == null) + { + AddError(new UndefinedNameReference(id.name, get_location(id))); + } + location lloc = get_location(id); + if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.type_node) + { + type_node tn = (type_node)sil.FirstOrDefault().sym_info; + indexer_as_type_indexes(tn, _indexer.indexes, mot, lloc); + return; + } + expression_node exp2 = ident_value_reciving(sil, id); + indexer_as_expression_index(exp2, _indexer.indexes, mot, get_location(id)); + return; + } + case general_node_type.expression: + { + expression_node ex = (expression_node)sn; + List sil = ex.type.find_in_type(id.name, context.CurrentScope); + if (sil == null) + { + AddError(new UndefinedNameReference(id.name, get_location(id))); + } + if (sil.FirstOrDefault().sym_info.general_node_type == general_node_type.property_node) + { + property_node pn = (property_node)sil.FirstOrDefault().sym_info; + if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + AddError(new CanNotReferenceToStaticPropertyWithExpression(pn, get_location(dotnd), ex.type)); + } + location lloc11 = get_location(dotnd); + try_convert_typed_expression_to_function_call(ref ex); + non_static_property_reference nspr = new non_static_property_reference(pn, ex, lloc11); + indexer_as_property_indexes(nspr, _indexer.indexes, mot, lloc11); + return; + } + expression_node en2 = expression_value_reciving(id, sil, ex, false); + indexer_as_expression_index(en2, _indexer.indexes, mot, get_location(id)); + return; + } + } + } + else + { + expression_node expr = convert_strong(_indexer.dereferencing_value); + indexer_as_expression_index(expr, _indexer.indexes, mot, get_location(_indexer.dereferencing_value)); + return; + } + } + } + + public override void visit(SyntaxTree.roof_dereference _roof_dereference) + { + expression_node exp = null; + var mot = motivation_keeper.motivation; + motivation_keeper.reset(); + + exp = convert_strong(_roof_dereference.dereferencing_value); + if (exp is typed_expression) exp = convert_typed_expression_to_function_call(exp as typed_expression); + //Check this expression + ref_type_node rtn = exp.type as ref_type_node; + //TODO: Сделать нормальное сообщение об ошибке. + if (rtn == null) + { + AddError(get_location(_roof_dereference.dereferencing_value), "CANNOT_DEREFER_THIS_EXPR_OF_NON_POINTER_TYPE"); + } + if (rtn.pointed_type == null) + AddError(get_location(_roof_dereference.dereferencing_value), "TYPE_{0}_IS_NOT_DETERMINED_COMPLETELY", rtn.PointedTypeName); + dereference_node res = new dereference_node(exp, get_location(_roof_dereference)); + switch (mot) + { + case motivation.address_receiving: return_addressed_value(res); break; + case motivation.expression_evaluation: return_value(res); break; + case motivation.semantic_node_reciving: return_semantic_value(res); break; + } + return; + } + + public override void visit(SyntaxTree.dereference _dereference) + { + throw new NotSupportedError(get_location(_dereference)); + } + + public override void visit(SyntaxTree.expression_list _expression_list) + { + //throw new NotSupportedError(get_location(_expression_list)); + int count = _expression_list.expressions.Count; + statement_node_list snl = new statement_node_list(); + for (int i = 0; i < count - 1; i++) + { + statement_node sn = ret.visit(_expression_list.expressions[i]); + snl.AddElement(sn); + } + expression_node ex = ret.visit(_expression_list.expressions[count - 1]); + statements_expression_node sen = new statements_expression_node( + snl, ex, get_location(_expression_list)); + return_value(sen); + } + + public override void visit(SyntaxTree.string_const _string_const) + { + expression_node en = null; + if (_string_const.Value.Length != 1) + { + en = new string_const_node(_string_const.Value, get_location(_string_const)); + if (SemanticRules.GenerateNativeCode && SemanticRules.StringType != null) + en.type = SemanticRules.StringType; + } + else + en = new char_const_node(Convert.ToChar(_string_const.Value), get_location(_string_const)); + + + return_value(en); + } + + public override void visit(SyntaxTree.program_name _program_name) + { + throw new NotSupportedError(get_location(_program_name)); + } + + public override void visit(SyntaxTree.program_tree _program_tree) + { + _program_tree.compilation_units[0].visit(this); + } + + public override void visit(SyntaxTree.declarations _subprogram_definitions) + { + if (SemanticRules.OrderIndependedTypeNames) + { + foreach (SyntaxTree.declaration sd in _subprogram_definitions.defs) + { + if (sd is SyntaxTree.type_declaration) + { + convertion_data_and_alghoritms.check_node_parser_error(sd); + sd.visit(this); + } + } + } + List namespaces = new List(); + foreach (SyntaxTree.declaration sd in _subprogram_definitions.defs) + { + convertion_data_and_alghoritms.check_node_parser_error(sd); + if (sd is syntax_namespace_node) + namespaces.Add(sd as syntax_namespace_node); + } + if (namespaces.Count > 0) + convert_pabc_namespaces(namespaces.ToArray()); + foreach (SyntaxTree.declaration sd in _subprogram_definitions.defs) + { + convertion_data_and_alghoritms.check_node_parser_error(sd); + if (!(sd is syntax_namespace_node)) + sd.visit(this); + } + if (SemanticRules.OrderIndependedFunctionNames) + { + visit_function_realizations(_subprogram_definitions); + context.clear_member_bindings(); + } + } + + public override void visit(SyntaxTree.declaration _subprogram_definition) + { + throw new NotSupportedError(get_location(_subprogram_definition)); + } + + private SyntaxTree.expression get_possible_array_const(SyntaxTree.expression expr, type_node tn, int rank) + { + try + { + if (tn == null) + return expr; + if (rank == 0) + return get_possible_array_const(expr, tn.element_type); + if (expr is SyntaxTree.bracket_expr) + { + SyntaxTree.array_const arr = new SyntaxTree.array_const(); + arr.source_context = expr.source_context; + arr.elements = new SyntaxTree.expression_list(); + arr.elements.expressions.Add(get_possible_array_const((expr as SyntaxTree.bracket_expr).expr, tn.element_type, rank - 1)); + return arr; + } + else if (expr is SyntaxTree.array_const) + { + SyntaxTree.array_const arr = expr as SyntaxTree.array_const; + if (arr.elements != null) + for (int i = 0; i < arr.elements.expressions.Count; i++) + arr.elements.expressions[i] = get_possible_array_const(arr.elements.expressions[i], tn.element_type, rank - 1); + return arr; + } + } + catch + { + + } + return expr; + } + + private SyntaxTree.expression get_possible_array_const(SyntaxTree.expression expr, type_node tn) + { + try + { + if (tn == null) + return expr; + if (expr is SyntaxTree.array_const && tn.BaseFullName != null && tn.BaseFullName.StartsWith("System.Tuple") && tn.type_special_kind != SemanticTree.type_special_kind.array_kind) + { + method_call mc = new method_call(); + mc.parameters = (expr as SyntaxTree.array_const).elements; + mc.dereferencing_value = new dot_node(new ident("Tuple", expr.source_context), new ident("Create", expr.source_context), expr.source_context); + return mc; + } + else if (expr is SyntaxTree.bracket_expr && (tn.type_special_kind == SemanticTree.type_special_kind.array_kind || tn.type_special_kind == SemanticTree.type_special_kind.array_wrapper)) + { + array_internal_interface aii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface; + if (aii != null && aii.rank > 1) + return get_possible_array_const(expr, tn, aii.rank); + SyntaxTree.array_const arr = new SyntaxTree.array_const(); + arr.source_context = expr.source_context; + arr.elements = new SyntaxTree.expression_list(); + arr.elements.expressions.Add(get_possible_array_const((expr as SyntaxTree.bracket_expr).expr, tn.element_type)); + return arr; + } + else if (expr is SyntaxTree.array_const && (tn.type_special_kind == SemanticTree.type_special_kind.array_kind || tn.type_special_kind == SemanticTree.type_special_kind.array_wrapper)) + { + array_internal_interface aii = tn.get_internal_interface(internal_interface_kind.unsized_array_interface) as array_internal_interface; + if (aii != null && aii.rank > 1) + return get_possible_array_const(expr, tn, aii.rank); + SyntaxTree.array_const arr = expr as SyntaxTree.array_const; + if (arr.elements != null) + for (int i = 0; i < arr.elements.expressions.Count; i++) + arr.elements.expressions[i] = get_possible_array_const(arr.elements.expressions[i], tn.element_type); + return arr; + } + else if (expr is SyntaxTree.record_const && tn is common_type_node) + { + common_type_node ctn = tn as common_type_node; + SyntaxTree.record_const rec = expr as SyntaxTree.record_const; + for (int i = 0; i < rec.rec_consts.Count; i++) + { + if (i < ctn.fields.Count) + rec.rec_consts[i].val = get_possible_array_const(rec.rec_consts[i].val, ctn.fields[i].type); + } + return rec; + } + } + catch + { + + } + return expr; + } + + public override void visit(SyntaxTree.var_def_statement _var_def_statement) + { + if (_var_def_statement.vars_type != null && _var_def_statement.vars_type is procedure_header) + { + var ph = _var_def_statement.vars_type as procedure_header; + if (ph.parameters != null) + foreach (var x in ph.parameters.params_list) + { + if (x.inital_value != null) + AddError(get_location(x.inital_value), "DEFAULT_PARAMS_IN_DELEGATE_TYPE"); // SSM bug fix #1463 + } + + } + + if (_var_def_statement.vars_type == null && _var_def_statement.inital_value is SyntaxTree.function_lambda_definition fld) + { + if (fld.formal_parameters != null && fld.formal_parameters.params_list.Select(x => x.vars_type).Any(x=>x is lambda_inferred_type)) + AddError(get_location(_var_def_statement.inital_value), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA"); + if (fld.return_type is lambda_inferred_type) + AddError(get_location(_var_def_statement.inital_value), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA"); + if (fld.return_type == null) + _var_def_statement.vars_type = new procedure_header(fld.formal_parameters, null, null, false, false, null, null, _var_def_statement.source_context); + else + _var_def_statement.vars_type = new function_header(fld.formal_parameters, null, null, null, fld.return_type, _var_def_statement.source_context); + //else + // AddError(get_location(_var_def_statement.inital_value), "IMPOSSIBLE_TO_INFER_TYPES_IN_LAMBDA"); //lroman// + } + + + if (_var_def_statement.vars_type == null && _var_def_statement.inital_value is SyntaxTree.pascal_set_constant pc) + { + if (pc.values==null || pc.values.Count == 0) + AddError(get_location(_var_def_statement.inital_value), "IMPOSSIBLE_TO_INFER_SET_TYPE"); + } + + + bool is_event = _var_def_statement.is_event; + + if (context.converting_block() == block_type.type_block && + context.converted_type.IsInterface && !is_event) + { + AddError(get_location(_var_def_statement), "INVALID_INTERFACE_MEMBER"); + } + + if (is_event && context.converting_block() == block_type.type_block && context.converted_type.IsInterface && (_var_def_statement.vars_type is function_header || _var_def_statement.vars_type is procedure_header)) + AddError(get_location(_var_def_statement.vars_type), "ANONYMOUS_DELEGATE_IN_INTERFACE_NOT_ALLOWED"); + + type_node tn = null; + expression_node inital_value = null; + if (_var_def_statement.vars_type != null) + { + tn = convert_strong(_var_def_statement.vars_type); + + if (tn.type_special_kind != SemanticTree.type_special_kind.array_kind && + tn.type_special_kind != SemanticTree.type_special_kind.array_wrapper && + !tn.BaseFullName.StartsWith("System.Tuple") && + _var_def_statement.inital_value is SyntaxTree.array_const ac) + { + AddError(get_location(_var_def_statement), "IMPOSSIBLE_TO_CONVERT_ARRAY_CONST_TO_{0}", tn); + } + + //LambdaHelper.InferTypesFromVarStmt(tn, _var_def_statement.inital_value as SyntaxTree.function_lambda_definition, this); //lroman// + if (tn.IsStatic && _var_def_statement.vars.idents[0].name != YieldHelpers.YieldConsts.Self) // SSM 10/07/19 fix #1639 в статическом классе можно только фиктивное поле с именем YieldHelpers.YieldConsts.Self описать - для того чтобы посмотреть на семантике его тип!!! + AddError(get_location(_var_def_statement), "VARIABLES_OF_STATIC_CLASS_NOT_ALLOWED"); + var fld1 = _var_def_statement.inital_value as SyntaxTree.function_lambda_definition; + if (fld1 != null) + { + MaybeConvertFunctionLambdaDefinitionToProcedureLambdaDefinition(fld1); + LambdaHelper.InferTypesFromVarStmt(tn, fld1, this); //lroman// + fld1.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; //SSM 12.2017 + } + + ref_type_node rt = tn as ref_type_node; + if (rt != null) + { + if (type_section_converting) + { + RefTypesForCheckPointersTypeForDotNetFramework.Add(rt); + } + else + { + CheckPointersTypeForDotNetFramework(rt.pointed_type, get_location(_var_def_statement.vars_type)); + } + } + if (is_event && !tn.IsDelegate) + AddError(get_location(_var_def_statement.vars_type), "EVENT_TYPE_MUST_BE_DELEGATE"); + check_for_type_allowed(tn,get_location(_var_def_statement.vars_type)); + if (_var_def_statement.vars_type is function_header || _var_def_statement.vars_type is procedure_header) + check_delegate_on_generic_parameters(tn as common_type_node, get_location(_var_def_statement.vars_type)); + if (context.converting_block() == block_type.type_block && context.converted_type.is_value_type && _var_def_statement.var_attr != SyntaxTree.definition_attribute.Static) + CheckForCircuralInRecord(tn, get_location(_var_def_statement.vars_type)); + if (_var_def_statement.inital_value != null) + if (is_event) AddError(new NotSupportedError(get_location(_var_def_statement.inital_value))); + else + { + _var_def_statement.inital_value = get_possible_array_const(_var_def_statement.inital_value,tn); + var ivc = convert_strong(_var_def_statement.inital_value); + inital_value = convert_strong_to_constant_or_function_call_for_varinit(ivc, tn); + if (!tn.IsDelegate && tn != SystemLibrary.SystemLibrary.object_type && inital_value is typed_expression && _var_def_statement.inital_value is addressed_value) + { + method_call mc = new method_call(); + mc.dereferencing_value = _var_def_statement.inital_value as addressed_value; + ivc = convert_strong(mc); + inital_value = convert_strong_to_constant_or_function_call_for_varinit(ivc, tn); + } + } + } + else + { + if (is_event) + AddError(get_location(_var_def_statement), "EVENT_MUST_HAVE_TYPE"); + var ex = convert_strong(_var_def_statement.inital_value); + expression_node cn = convert_strong_to_constant_or_function_call_for_varinit(ex); + if (cn is constant_node) + (cn as constant_node).SetType(DeduceType(cn.type, get_location(_var_def_statement.inital_value))); + inital_value = cn; + tn = inital_value.type; + if (tn is null_type_node) + AddError(cn.location, "CAN_NOT_DEDUCE_TYPE_{0}", tn.name); + if (context.converting_block() == block_type.type_block && context.converted_type.is_value_type && _var_def_statement.var_attr != SyntaxTree.definition_attribute.Static) + CheckForCircuralInRecord(tn, get_location(_var_def_statement)); + } + if (inital_value != null && inital_value is typed_expression) + { + inital_value = convert_typed_expression_to_function_call(inital_value as typed_expression); + tn = inital_value.type; + if (inital_value is typed_expression) + { + base_function_call bfc = ((inital_value as typed_expression).type as delegated_methods).proper_methods[0]; + if (bfc.function.is_generic_function && _var_def_statement.vars_type == null) + { + AddError(inital_value.location, "CAN_NOT_DEDUCE_TYPE_{0}", null); + } + foreach (parameter p in bfc.simple_function_node.parameters) + { + if (p.type.is_generic_parameter) + AddError(inital_value.location, "USE_ANONYMOUS_FUNCTION_TYPE_WITH_GENERICS"); + } + common_type_node del = + convertion_data_and_alghoritms.type_constructor.create_delegate(context.get_delegate_type_name(), bfc.simple_function_node.return_value_type, bfc.simple_function_node.parameters, context.converted_namespace, null); + context.converted_namespace.types.AddElement(del); + tn = del; + inital_value = convertion_data_and_alghoritms.explicit_convert_type(inital_value, del); + inital_value.type = tn; + } + else if (inital_value is base_function_call) + { + base_function_call bfc = inital_value as base_function_call; + if (bfc.function.is_generic_function && _var_def_statement.vars_type == null) + { + AddError(inital_value.location, "CAN_NOT_DEDUCE_TYPE_{0}", null); + } + } + } + foreach (SyntaxTree.ident id in _var_def_statement.vars.idents) + { + location lid = get_location(id); + SemanticTree.polymorphic_state ps = SemanticTree.polymorphic_state.ps_common; + if (_var_def_statement.var_attr == SyntaxTree.definition_attribute.Static) + ps = SemanticTree.polymorphic_state.ps_static; + if (!is_event) + { + var_definition_node vdn = context.add_var_definition(id.name, lid, ps); + assign_doc_info(vdn,_var_def_statement); + if (_var_def_statement.attributes != null) + { + make_attributes_for_declaration(_var_def_statement, vdn); + } + } + else + { + event_node ce = null; + if (context.converted_type != null && context.converted_type.IsInterface) + ps = SemanticTree.polymorphic_state.ps_virtual_abstract; + if (context.converted_type != null) + ce = context.add_event_definition(id.name, lid, tn, ps, context.converted_type.IsInterface); + else if (context.top_function == null) + ce = context.add_namespace_event(id.name, lid, tn); + else + AddError(lid, "EVENT_MUST_BE_IN_CLASS_OR_NAMESPACE"); + assign_doc_info(ce,_var_def_statement); + if (_var_def_statement.attributes != null) + { + make_attributes_for_declaration(_var_def_statement, ce); + } + } + } + if (context.converted_type != null && context.converting_block() == block_type.type_block && context.converted_type.IsStatic && _var_def_statement.var_attr != definition_attribute.Static) + AddError(get_location(_var_def_statement), "STATIC_CLASSES_CANNOT_NON_STATIC_MEMBERS"); + if (is_event) return; + context.save_var_definitions(); + + context.restore_var_definitions(); + context.close_var_definition_list(tn, inital_value); + if (!SemanticRules.ManyVariablesOneInitializator && _var_def_statement.inital_value != null && _var_def_statement.vars.idents.Count > 1) + AddError(get_location(_var_def_statement.inital_value), "ONE_VARIABLE_ONE_INITIALIZATOR"); + } + + private void CheckForCircularityInPointers(ref_type_node left, type_node right, location loc) + { + if (left == null || right == null) + return; + if (left == right) + // #ErrorRefactoringProblem + // AddError(loc, "CIRCULARITY_IN_POINTER"); // Если заменить этой строкой следующую, то при запуске bin\TestRunner.exe это приложение зацикливается, что сопровождается утечкой памяти + AddError(new CircuralityInPointer(loc)); + if (right is ref_type_node) + CheckForCircularityInPointers(left, (right as ref_type_node).pointed_type, loc); + else if (right.type_special_kind == SemanticTree.type_special_kind.array_kind || right.type_special_kind == SemanticTree.type_special_kind.array_wrapper) + CheckForCircularityInPointers(left,right.element_type,loc); + } + + private void CheckForCircuralInRecord(type_node tn, location loc) + { + if (tn == context.converted_type || tn.original_generic == context.converted_type) + { + AddError(loc, "CIRCULARITY_IN_RECORD"); + } + if (tn is common_type_node) + { + common_type_node ctn = tn as common_type_node; + if (ctn.is_value_type) + { + foreach (class_field fld in ctn.fields) + if (fld.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + CheckForCircuralInRecord(fld.type, loc); + } + else + { + foreach (class_field fld in ctn.fields) + if (fld.polymorphic_state != SemanticTree.polymorphic_state.ps_static && fld.type is simple_array) + CheckForCircuralInRecord((fld.type as simple_array).element_type, loc); + } + } + } + + //Пытается вывести тип + private type_node DeduceType(type_node tn, location loc) + { + if (tn is undefined_type || tn is null_type_node) + { + if (tn is ArrayConstType) + return convertion_data_and_alghoritms.type_constructor.create_unsized_array((tn as ArrayConstType).element_type, context.converted_namespace, 1, loc); + AddError(loc, "CAN_NOT_DEDUCE_TYPE_{0}", tn.name); + } + return tn; + } + + public override void visit(SyntaxTree.ident_list _ident_list) + { + throw new NotSupportedError(get_location(_ident_list)); + } + + public override void visit(SyntaxTree.variable_definitions _variable_definitions) + { + bool is_event = false; + foreach (SyntaxTree.var_def_statement vds in _variable_definitions.var_definitions) + { + convertion_data_and_alghoritms.check_node_parser_error(vds); + if (vds.is_event && !is_event) + is_event = true; + else if (is_event) + vds.is_event = true; + vds.visit(this); + } + } + + public override void visit(SyntaxTree.named_type_reference _named_type_reference) + { + var loc = get_location(_named_type_reference); + type_node tn = find_type(_named_type_reference, loc); + return_value(tn); + } + + public override void visit(SyntaxTree.type_definition _type_definition) + { + throw new NotSupportedError(get_location(_type_definition)); + } + + public override void visit(SyntaxTree.addressed_value _addressed_value) + { + throw new NotSupportedError(get_location(_addressed_value)); + } + + private addressed_expression ident_address_reciving(SymbolInfo si, SyntaxTree.ident _ident) + { + location lloc = get_location(_ident); + definition_node dn = null; + if (!internal_is_assign) + dn = context.check_name_node_type(_ident.name, si, lloc, + general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node); + else + dn = context.check_name_node_type(_ident.name, si, lloc, + general_node_type.variable_node, general_node_type.property_node, general_node_type.event_node, general_node_type.constant_definition); + if (dn.general_node_type == general_node_type.constant_definition) + AddError(get_location(_ident), "CAN_NOT_ASSIGN_TO_CONSTANT_OBJECT"); + switch (dn.general_node_type) + { + case general_node_type.variable_node: + { + local_variable lv = dn as local_variable; + if (lv != null && (lv.function is common_method_node)) + { + //self variable + if ((lv.function as common_method_node).self_variable == lv) + { + AddError(lloc, "VARIABLE_{0}_READONLY", lv.name); + } + } + return create_variable_reference(dn, lloc); + } + case general_node_type.property_node: + { + property_node pn = (property_node)dn; + if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + static_property_reference spr = new static_property_reference(pn, lloc); + return spr; + } + //this_node thisnode=new this_node(context.converted_type,lloc); + if (pn.comprehensive_type.Scope == null && pn is compiled_property_node) + (pn.comprehensive_type as compiled_type_node).init_scope(); + non_static_property_reference nspr = new non_static_property_reference(pn, GetCurrentObjectReference(pn.comprehensive_type.Scope, pn, lloc), lloc); + return nspr; + } + case general_node_type.event_node: + { + if (dn.semantic_node_type == semantic_node_type.compiled_event) + { + compiled_event ce = (compiled_event)dn; + if (ce.is_static) + { + static_event_reference ser = new static_event_reference(ce, get_location(_ident)); + return ser; + } + nonstatic_event_reference nser = new nonstatic_event_reference( + GetCurrentObjectReference(ce.comprehensive_type.Scope, ce, lloc), ce, lloc); + return nser; + } + else if (dn.semantic_node_type == semantic_node_type.common_event) + { + common_event ce = (common_event)dn; + if (ce.is_static) + { + static_event_reference ser = new static_event_reference(ce, get_location(_ident)); + return ser; + } + nonstatic_event_reference nser = new nonstatic_event_reference( + GetCurrentObjectReference(ce.comprehensive_type.Scope, ce, lloc), ce, lloc); + return nser; + } + else if (dn.semantic_node_type == semantic_node_type.common_namespace_event) + { + common_namespace_event cne = (common_namespace_event)dn; + static_event_reference ser = new static_event_reference(cne, get_location(_ident)); + return ser; + } + break; + } + } + return null; + } + + private expression_node ident_value_reciving(List sil, SyntaxTree.ident _ident) + { + //SymbolInfo si=blocks.find(_ident.name); + location lloc = get_location(_ident); + definition_node dn = context.check_name_node_type(_ident.name, sil?.FirstOrDefault(), get_location(_ident), general_node_type.variable_node, + general_node_type.function_node, general_node_type.property_node, general_node_type.constant_definition, + general_node_type.event_node); + switch (dn.general_node_type) + { + case general_node_type.constant_definition: + { + constant_definition_node cdn = (constant_definition_node)dn; + if (cdn.const_value is array_const || cdn.const_value is record_constant || cdn.const_value is common_namespace_function_call_as_constant) + { + return create_constant_reference(cdn,lloc); + } + if (cdn.const_value == null) + AddError(new UndefinedNameReference(cdn.name,get_location(_ident))); + constant_node cn = cdn.const_value.get_constant_copy(get_location(_ident)); + if (cn != null) return cn; + return cdn.const_value; + } + case general_node_type.variable_node: + { + local_variable lv = dn as local_variable; + if (lv != null && (lv.function is common_method_node)) + { + //self variable + if ((lv.function as common_method_node).self_variable == lv) + //return new this_node((lv.function as common_method_node).cont_type, lloc); + return new this_node(lv.type, lloc); + //return GetCurrentObjectReference((lv.function as common_method_node).cont_type.Scope, lloc); + } + return create_variable_reference(dn, lloc); + } + case general_node_type.function_node: + { + //return convertion_data_and_alghoritms.create_full_function_call(new expressions_list(), + // si,lloc,blocks.converted_type,blocks.top_function,false); + if (SystemUnitAssigned && SystemLibrary.SystemLibInitializer.PascalABCVersion.Equal(sil)) + { + return new string_const_node(RevisionClass.FullVersion, get_location(_ident)); + } + if (sil.FirstOrDefault().sym_info == SystemLibrary.SystemLibInitializer.NewProcedure.sym_info) + { + AddError(lloc, "EXPECTED_TYPE_AFTER_NEW"); + } + if (sil.FirstOrDefault().sym_info == SystemLibrary.SystemLibInitializer.DisposeProcedure.sym_info) + { + AddError(lloc, "CANNOT_GET_POINTER_TO_DISPOSE"); + } + if (sil.FirstOrDefault().sym_info is common_method_node && (sil.FirstOrDefault().sym_info as common_method_node).is_constructor) + return convertion_data_and_alghoritms.create_full_function_call(new expressions_list(), + sil, lloc, context.converted_type, context.top_function, false); + if (!(sil.FirstOrDefault().sym_info is common_in_function_function_node)) + { + var ex = sil.FirstOrDefault().sym_info as basic_function_node; + if (ex != null && ex.name.ToLower() == "exit") + return new basic_function_call(ex, ex.location); + return make_delegate_wrapper(null, sil, lloc, ((sil.FirstOrDefault().sym_info is common_method_node) && ((common_method_node)sil.FirstOrDefault().sym_info).IsStatic)); + } + return convertion_data_and_alghoritms.create_full_function_call(new expressions_list(), + sil, lloc,context.converted_type,context.top_function,false); + } + case general_node_type.property_node: + { + property_node pn = (property_node)dn; + function_node fn = pn.get_function; + if (fn == null) + { + AddError(new ThisPropertyCanNotBeReaded(pn, lloc)); + } + if (pn.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + return create_static_method_call(fn, lloc, pn.comprehensive_type, false); + } + check_property_no_params(pn, lloc); + //this_node thisnode = new this_node(context.converted_type, lloc); + if (pn.comprehensive_type.Scope == null && pn is compiled_property_node) + (pn.comprehensive_type as compiled_type_node).init_scope(); + return create_not_static_method_call(fn, GetCurrentObjectReference(pn.comprehensive_type.Scope, fn, lloc), lloc, false); + } + case general_node_type.event_node: + { + if (dn.semantic_node_type == semantic_node_type.compiled_event) + { + compiled_event ce = (compiled_event)dn; + if (ce.is_static) + { + static_event_reference ser = new static_event_reference(ce, get_location(_ident)); + return ser; + } + nonstatic_event_reference nser = new nonstatic_event_reference( + new this_node(context.converted_type, lloc), ce, lloc); + return nser; + } + else if (dn.semantic_node_type == semantic_node_type.common_event) + { + common_event ce = (common_event)dn; + if (ce.is_static) + { + static_event_reference ser = new static_event_reference(ce, get_location(_ident)); + return ser; + } + nonstatic_event_reference nser = new nonstatic_event_reference( + new this_node(context.converted_type, lloc), ce, lloc); + return nser; + } + else if (dn.semantic_node_type == semantic_node_type.common_namespace_event) + { + common_namespace_event cne = (common_namespace_event)dn; + if (_compiled_unit.namespaces.IndexOf(cne.namespace_node) != -1) + { + static_event_reference ser = new static_event_reference(cne, get_location(_ident)); + return ser; + } + else + AddError(get_location(_ident), "EVENT_{0}_MUST_BE_IN_LEFT_PART", cne.name); + } + break; + } + } + return null; + } + + private expression_node create_constant_reference(constant_definition_node cdn, location loc) + { + if (cdn is namespace_constant_definition) + return new namespace_constant_reference(cdn as namespace_constant_definition,loc); + else if (cdn is function_constant_definition) + return new function_constant_reference(cdn as function_constant_definition,loc); + else + return cdn.const_value; + } + + private List find_in_base(SyntaxTree.inherited_message ident) + { + if (context.converted_type == null) + { + AddError(get_location(ident), "INHERITED_EXPECTED_IN_CLASS"); + } + if (context.converted_type.base_type == null) + { + AddError(get_location(ident), "NO_BASE_CLASS_DEFINED_BUT_INHERITED_MEET"); + } + common_method_node cmn = context.converted_func_stack.first() as common_method_node; + if (cmn == null) + { + AddError(get_location(ident), "NAME_IN_BASE_CLASS_MUST_BE_METHOD"); + } + + List sil = null; + if (cmn.is_constructor) + sil = context.converted_type.base_type.find_in_type(compiler_string_consts.default_constructor_name, context.CurrentScope); + else + sil = context.converted_type.base_type.find_in_type(cmn.name, context.CurrentScope); + if (sil != null) + { + while (sil.Count != 0) + { + if (!cmn.is_constructor) + { + if (sil.FirstOrDefault().sym_info is function_node && convertion_data_and_alghoritms.function_eq_params_and_result(sil.FirstOrDefault().sym_info as function_node, cmn)) + return sil; + } + else + { + if (sil.FirstOrDefault().sym_info is function_node && convertion_data_and_alghoritms.function_eq_params(sil.FirstOrDefault().sym_info as function_node, cmn)) + return sil; + } + sil.RemoveAt(0); + } + sil = null; + } + if (cmn.is_constructor) + AddError(get_location(ident), "NO_CONSTRUCTOR_IN_BASE_CLASS_WITH_SAME_PARAMETERS"); + else + AddError(get_location(ident), "NAME_IN_BASE_CLASS_MUST_BE_METHOD"); + return sil; + /*if (si == null) + { + throw new UndefinedNameReference(name, get_location(ident)); + } + if (!(si.sym_info is common_method_node) && !(si.sym_info is compiled_function_node)) + { + throw new NameInBaseClassMustBeMethod(name, get_location(ident)); + } + common_function_node cfn = si.sym_info as common_function_node;*/ + } + + private List find_in_base(SyntaxTree.inherited_ident ident) + { + if (context.converted_type == null) + { + AddError(get_location(ident), "INHERITED_EXPECTED_IN_CLASS"); + } + if (context.converted_type.base_type == null) + { + AddError(get_location(ident), "NO_BASE_CLASS_DEFINED_BUT_INHERITED_MEET"); + } + List sil = context.converted_type.base_type.find_in_type(ident.name, context.CurrentScope); + if (sil == null) + { + sil = context.converted_namespace.find(ident.name); + if (sil != null) + AddError(get_location(ident), "CLASS_MEMBER_{0}_EXPECTED", ident.name); + else + AddError(new UndefinedNameReference(ident.name, get_location(ident))); + } + return sil; + } + + private addressed_expression inherited_ident_address_reciving(SyntaxTree.inherited_ident _ident) + { + List sil = find_in_base(_ident); + return ident_address_reciving(sil?.FirstOrDefault(), _ident); + } + + private addressed_expression ident_address_reciving(SyntaxTree.ident _ident) + { + if ((context.converting_block() == block_type.function_block) && (context.top_function.return_variable != null)) + { + List sil = context.top_function.scope.FindOnlyInScope(_ident.name); // почему-то не находит локальную переменную с этим именем + // тут баг #2401 + // context.find_only_in_namespace(_ident.name); // это было закомментировано 10.01.21 + if (sil == null) + { + int comp = SystemLibrary.SystemLibrary.string_comparer.Compare(_ident.name, context.top_function.name); + if (comp == 0) // мы нашли функцию и ее имя совпадает с ident + { + List mysi = context.find(_ident.name); + if (mysi != null && mysi[0].sym_info is function_node) + { + local_variable lv = context.top_function.return_variable; + return new local_variable_reference(lv, 0, get_location(_ident)); + } + } + } + } + List idsi = context.find(_ident.name); + + return ident_address_reciving(idsi?.FirstOrDefault(), _ident); + } + + internal addressed_expression create_variable_reference(definition_node dn, location lloc) + { + switch (dn.semantic_node_type) + { + case semantic_node_type.local_variable: + { + local_variable lv = (local_variable)dn; + if (context.converting_block() == block_type.function_block) + { + return new local_variable_reference(lv, + convertion_data_and_alghoritms.symbol_table.GetRelativeScopeDepth(lv.function.scope, context.top_function.scope), lloc); + } + else if (context.converting_block() == block_type.namespace_block) + { + return new local_variable_reference(lv, 0, lloc); + } + else + { + throw new CompilerInternalError("Invalid block type"); + } + } + case semantic_node_type.namespace_variable: + { + namespace_variable nv = (namespace_variable)dn; + return new namespace_variable_reference(nv, lloc); + } + case semantic_node_type.class_field: + { + class_field cf = (class_field)dn; + if (cf.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + { + return new static_class_field_reference(cf, lloc); + } + expression_node obj = GetCurrentObjectReference(cf.cont_type.Scope,cf, lloc); //new this_node(context.converted_type, lloc); + return new class_field_reference(cf, obj, lloc); + } + case semantic_node_type.common_parameter: + { + if (context.in_parameters_block) + AddError(new ParameterReferenceInDefaultParameterNotAllowed(lloc)); + common_parameter cpar = (common_parameter)dn; + return new common_parameter_reference(cpar, + convertion_data_and_alghoritms.symbol_table.GetRelativeScopeDepth(cpar.common_function.scope, context.top_function.scope), lloc); + } + case semantic_node_type.local_block_variable: + { + return new local_block_variable_reference((local_block_variable)dn, lloc); + } + case semantic_node_type.compiled_variable_definition: + { + compiled_variable_definition cvd = dn as compiled_variable_definition; + if (cvd.polymorphic_state == SemanticTree.polymorphic_state.ps_static) + return new static_compiled_variable_reference(cvd, lloc); + expression_node obj = GetCurrentObjectReference(cvd.cont_type.Scope, cvd, lloc); //new this_node(context.converted_type, lloc); + return new compiled_variable_reference(cvd, obj, lloc); + } + default: throw new NotSupportedError(lloc); + } + return null; + } + + private expression_node ident_value_reciving(SyntaxTree.ident _ident) + { + List sil = context.find(_ident.name); + return ident_value_reciving(sil, _ident); + } + + private expression_node inherited_message_value_reciving(SyntaxTree.inherited_message _ident) + { + List sil = find_in_base(_ident); + bool constr = false; + if (sil != null) + if (sil.FirstOrDefault().sym_info is common_method_node) + { + if ((sil.FirstOrDefault().sym_info as common_method_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) + AddError(get_location(_ident), "CANNOT_CALL_ABSTRACT_METHOD"); + constr = (sil.FirstOrDefault().sym_info as common_method_node).is_constructor; + } + else + if (sil.FirstOrDefault().sym_info is compiled_function_node) + { + if ((sil.FirstOrDefault().sym_info as compiled_function_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) + AddError(get_location(_ident), "CANNOT_CALL_ABSTRACT_METHOD"); + } + else if (sil.FirstOrDefault().sym_info is compiled_constructor_node) + { + constr = true; + } + location loc = get_location(_ident); + function_node fn = sil.FirstOrDefault().sym_info as function_node; + base_function_call bfc = null; + common_function_node cfn = context.converted_func_stack.first(); + int depth = context.converted_func_stack.size-1; + if (!constr) + { + if (fn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + { + bfc = create_not_static_method_call(fn,new this_node(context.converted_type,loc),loc,true); + if (bfc is common_method_call) + (bfc as common_method_call).virtual_call = false; + else + (bfc as compiled_function_call).virtual_call = false; + } + else if (fn is common_method_node) + bfc = create_static_method_call(fn,loc,(fn as common_method_node).cont_type,true); + else if (fn is compiled_function_node) + bfc = create_static_method_call(fn,loc,(fn as compiled_function_node).cont_type,true); + else + throw new NotSupportedError(loc); + } + else + { + if (!context.allow_inherited_ctor_call && !context.can_call_inherited_ctor_call(convertion_data_and_alghoritms.statement_list_stack_first())) + AddError(loc, "INHERITED_CONSTRUCTOR_CALL_MUST_BE_FIRST"); + expressions_list exprs = new expressions_list(); + foreach (common_parameter cp in cfn.parameters) + { + exprs.AddElement(new common_parameter_reference(cp,depth,loc)); + } + if (fn is common_method_node) + { + common_constructor_call ccc = create_constructor_call((fn as common_method_node).cont_type,exprs,loc) as common_constructor_call; + ccc._new_obj_awaited = false; + return ccc; + } + else if (fn is compiled_constructor_node) + { + compiled_constructor_call ccc = create_constructor_call((fn as compiled_constructor_node).compiled_type,exprs,loc) as compiled_constructor_call; + ccc._new_obj_awaited = false; + return ccc; + } + else + throw new NotSupportedError(loc); + } + + foreach (common_parameter cp in cfn.parameters) + { + bfc.parameters.AddElement(new common_parameter_reference(cp,depth,loc)); + } + return bfc; + } + + private expression_node inherited_ident_value_reciving(SyntaxTree.inherited_ident _ident) + { + List sil = find_in_base(_ident); + if (sil != null) + if (sil.FirstOrDefault().sym_info is common_method_node) + { + if ((sil.FirstOrDefault().sym_info as common_method_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) + AddError(get_location(_ident), "CANNOT_CALL_ABSTRACT_METHOD"); + } + else + if (sil.FirstOrDefault().sym_info is compiled_function_node) + { + if ((sil.FirstOrDefault().sym_info as compiled_function_node).polymorphic_state == SemanticTree.polymorphic_state.ps_virtual_abstract) + AddError(get_location(_ident), "CANNOT_CALL_ABSTRACT_METHOD"); + } + return ident_value_reciving(sil, _ident); + } + + + private semantic_node ident_semantic_reciving(SyntaxTree.ident _ident) + { + List si_left = context.find(_ident.name); + return ident_semantic_reciving(si_left, _ident); + } + + private semantic_node inherited_ident_semantic_reciving(SyntaxTree.inherited_ident _ident) + { + List sil = find_in_base(_ident); + return ident_semantic_reciving(sil, _ident); + } + + private semantic_node ident_semantic_reciving(List si_left, SyntaxTree.ident _ident) + { + //SymbolInfo si_left=blocks.find(_ident.name); + location lloc = get_location(_ident); + if (si_left == null) + { + AddError(new UndefinedNameReference(_ident.name, lloc)); + } + definition_node dn = context.check_name_node_type(_ident.name, si_left?.FirstOrDefault(), get_location(_ident), + general_node_type.constant_definition, general_node_type.function_node, + general_node_type.namespace_node, general_node_type.property_node, + general_node_type.type_node, general_node_type.variable_node, + general_node_type.unit_node); + switch (dn.general_node_type) + { + case general_node_type.constant_definition: + case general_node_type.function_node: + case general_node_type.property_node: + case general_node_type.variable_node: + { + return ident_value_reciving(si_left, _ident); + } + case general_node_type.namespace_node: + { + //throw new CompilerInternalError("Unsupported now."); + return dn; + } + case general_node_type.type_node: + { + type_node tn = dn as type_node; + //dot_node_as_type_ident(tn,id_right,mot); + return tn; + } + case general_node_type.unit_node: + { + //throw new CompilerInternalError("Unsupproted now."); + //throw new NotSupportedError(get_location(_ident)); + return dn; + } + } + return null; + } + + public override void visit(SyntaxTree.ident _ident) + { + if (_ident.name.IndexOf('.') != -1) + { + var arr = _ident.name.Split('.'); + var dn = new dot_node(new ident(_ident.name.Substring(0, _ident.name.LastIndexOf('.')), _ident.source_context), new ident(arr[arr.Length - 1], _ident.source_context)); + dn.visit(this); + return; + } + var mot = motivation_keeper.motivation; + motivation_keeper.reset(); + switch (mot) + { + case motivation.address_receiving: return_addressed_value(ident_address_reciving(_ident)); break; + case motivation.expression_evaluation: return_value(ident_value_reciving(_ident)); break; + //case motivation.symbol_info_reciving: return_symbol_value(blocks.find(_ident.name));break; + case motivation.semantic_node_reciving: return_semantic_value(ident_semantic_reciving(_ident)); break; + default: throw new NotSupportedError(get_location(_ident)); + } + return; + } + + public override void visit(SyntaxTree.subprogram_body _subprogram_body) + { + throw new NotSupportedError(get_location(_subprogram_body)); + } + + public override void visit(SyntaxTree.statement _statement) + { + throw new NotSupportedError(get_location(_statement)); + } + + public override void visit(SyntaxTree.double_const _double_const) + { + expression_node en = new double_const_node(_double_const.val, get_location(_double_const)); + var mot = motivation_keeper.motivation; + motivation_keeper.reset(); + switch (mot) + { + case motivation.address_receiving: throw new CompilerInternalError("Addres receiving from constant"); + case motivation.expression_evaluation: return_value(en); break; + case motivation.semantic_node_reciving: return_semantic_value(en); break; + } + //return_value(en); + return; + } + + public override void visit(SyntaxTree.bigint_const bi) + { + var names = new List { new ident("System"), new ident("Numerics"), new ident("BigInteger") }; + var ntr = new named_type_reference(names, bi.source_context); + var ne = new new_expr(ntr, new expression_list(new uint64_const(bi.val)),bi.source_context); + visit(ne); + } + + + public override void visit(SyntaxTree.int32_const int32) + { + + //таблица целых констант на уровне синтаксиса + // - 0 + + // 32--------16----8----|----8----16--------32----------------64(bits) + // [ int64 )[ int32 ]( int64 ]( uint64 ] + + //таблица целых констант на уровне семантики(???) + // - 0 + + // 32--------16----8----|----8----16--------32----------------64(bits) + // [ long )[ int )[byte](int]( long ]( ulong ] + + //Отлюченно временно (из-за ошибок временно алгоритмах выбора оперетора?) + /*if(int32.val>=byte.MinValue && int32.val<=byte.MaxValue) + return_value(new byte_const_node((byte)int32.val, get_location(int32))); + else*/ + expression_node en = null; + /* + if ((int32.val >= byte.MinValue) && (int32.val <= byte.MaxValue)) + { + en = new byte_const_node((byte)int32.val, get_location(int32)); + } + else + { + en = new int_const_node(int32.val, get_location(int32)); + } + */ + en = SystemLibrary.static_executors.make_int_const(int32.val, get_location(int32)); + var mot = motivation_keeper.motivation; + motivation_keeper.reset(); + switch (mot) + { + case motivation.address_receiving: throw new CompilerInternalError("Addres receiving from constant"); + case motivation.expression_evaluation: return_value(en); break; + case motivation.semantic_node_reciving: return_semantic_value(en); break; + } + //return_value(en); + return; + } + + public override void visit(SyntaxTree.int64_const int64) + { + expression_node en = new long_const_node(int64.val, get_location(int64)); + var mot = motivation_keeper.motivation; + motivation_keeper.reset(); + switch (mot) + { + case motivation.address_receiving: throw new CompilerInternalError("Addres receiving from constant"); + case motivation.expression_evaluation: return_value(en); break; + case motivation.semantic_node_reciving: return_semantic_value(en); break; + } + //return_value(en); + return; + } + + public override void visit(SyntaxTree.uint64_const uint64) + { + //TODO добавить обработку + // :-) + //throw new CompilerInternalError("Числа UInt64 доступны только в PascalABC.NET Professional Edition"); + expression_node en = new ulong_const_node(uint64.val, get_location(uint64)); + var mot = motivation_keeper.motivation; + motivation_keeper.reset(); + switch (mot) + { + case motivation.address_receiving: throw new CompilerInternalError("Addres receiving from constant"); + case motivation.expression_evaluation: return_value(en); break; + case motivation.semantic_node_reciving: return_semantic_value(en); break; + } + return; + } + + + public override void visit(SyntaxTree.bool_const _bool_const) + { + expression_node en = new bool_const_node(_bool_const.val, get_location(_bool_const)); + var mot = motivation_keeper.motivation; + motivation_keeper.reset(); + switch (mot) + { + case motivation.address_receiving: throw new CompilerInternalError("Address receiving from constant"); + case motivation.expression_evaluation: return_value(en); break; + case motivation.semantic_node_reciving: return_semantic_value(en); break; + } + //return_value(en); + return; + } + + public override void visit(SyntaxTree.const_node _const_node) + { + throw new NotSupportedError(get_location(_const_node)); + } + + public override void visit(SyntaxTree.un_expr _un_expr) + { + expression_node exp = convert_strong(_un_expr.subnode); + expression_node res = find_operator(_un_expr.operation_type, exp, get_location(_un_expr)); + return_value(res); + } + + public override void visit(SyntaxTree.bin_expr _bin_expr) + { + expression_node left = convert_strong(_bin_expr.left); + expression_node right = convert_strong(_bin_expr.right); + if (_bin_expr.operation_type == Operators.In) + try_convert_typed_expression_to_function_call(ref left); + expression_node res = find_operator(_bin_expr.operation_type, left, right, get_location(_bin_expr)); + + if (res.type is undefined_type) + AddError(get_location(_bin_expr), "OPERATOR_RETURN_TYPE_UNDEFINED_{0}", name_reflector.get_name(_bin_expr.operation_type)); + if (res.type.type_special_kind == SemanticTree.type_special_kind.base_set_type) + { + if (left.type.element_type == right.type.element_type) + res.type = left.type; + else if (type_table.compare_types(left.type, right.type) == type_compare.greater_type) + res.type = left.type; + else if (type_table.compare_types(left.type, right.type) == type_compare.less_type) + res.type = right.type; + else if (type_table.compare_types(left.type, right.type) == type_compare.non_comparable_type) + res.type = context.create_set_type(SystemLibrary.SystemLibrary.object_type, get_location(_bin_expr)); + } + //ssyy, 15.05.2009 + switch (_bin_expr.operation_type) + { + case PascalABCCompiler.SyntaxTree.Operators.Equal: + case PascalABCCompiler.SyntaxTree.Operators.NotEqual: + if (left.type.is_generic_parameter && right.type.is_generic_parameter) + { + compiled_static_method_call cfc = new compiled_static_method_call( + SystemLibrary.SystemLibrary.object_equals_method, get_location(_bin_expr)); + cfc.parameters.AddElement(left); + cfc.parameters.AddElement(right); + if (_bin_expr.operation_type == PascalABCCompiler.SyntaxTree.Operators.NotEqual) + { + res = new basic_function_call(SystemLibrary.SystemLibrary.bool_not as basic_function_node, get_location(_bin_expr), cfc); + } + else + { + res = cfc; + } + } + else if (left is static_event_reference) + { + if ((left as static_event_reference).en is compiled_event) + AddError(left.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (left as static_event_reference).en.name); + if (context.converted_type != null && context.converted_type != ((left as static_event_reference).en as common_event).cont_type && !context.converted_type.name.Contains("<>local_variables_class")) + AddError(left.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (left as static_event_reference).en.name); + } + else if (right is static_event_reference) + { + if ((right as static_event_reference).en is compiled_event) + AddError(right.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (right as static_event_reference).en.name); + if (context.converted_type != null && context.converted_type != ((right as static_event_reference).en as common_event).cont_type) + AddError(right.location, "EVENT_{0}_MUST_BE_IN_LEFT_PART", (right as static_event_reference).en.name); + } + break; + } + return_value(res); + } + + private void check_property_no_params(property_node pn, location loc) + { + if (pn.parameters.Count != 0) + { + AddError(loc, "PROPERTY_{0}_REFERENCE_WITH_INVALID_PARAMS_COUNT", pn.name); + } + } + + private void check_property_params(static_property_reference pr, location loc) + { + if (pr.property.parameters.Count != pr.fact_parametres.Count) + { + AddError(loc, "PROPERTY_{0}_REFERENCE_WITH_INVALID_PARAMS_COUNT", pr.property.name); + } + } + + private void check_property_params(non_static_property_reference pr, location loc) + { + if (pr.property.parameters.Count != pr.fact_parametres.Count) + { + AddError(loc, "PROPERTY_{0}_REFERENCE_WITH_INVALID_PARAMS_COUNT", pr.property.name); + } + } + + private SyntaxTree.procedure_call ConvertEventOperationToProcedureCall(SyntaxTree.assign _assign) + { + SyntaxTree.ident event_name = _assign.to as SyntaxTree.ident; + SyntaxTree.dot_node dot = _assign.to as SyntaxTree.dot_node; + if (dot != null) + event_name = dot.right as SyntaxTree.ident; + if (event_name == null) + AddError(new EventNameExpected(get_location(_assign.to))); + string format; + if (_assign.operator_type == PascalABCCompiler.SyntaxTree.Operators.AssignmentSubtraction) + format = compiler_string_consts.event_remove_method_nameformat; + else + format = compiler_string_consts.event_add_method_nameformat; + SyntaxTree.ident add_name = new SyntaxTree.ident(string.Format(format, event_name.name)); + add_name.source_context = event_name.source_context; + if (dot != null) + dot.right = add_name; + SyntaxTree.expression_list exprlist = new SyntaxTree.expression_list(); + exprlist.expressions.Add(_assign.from); + exprlist.source_context = _assign.to.source_context; + SyntaxTree.method_call add_methcall = new SyntaxTree.method_call(exprlist); + if (dot != null) + add_methcall.dereferencing_value = dot; + else + add_methcall.dereferencing_value = add_name; + add_methcall.source_context = _assign.source_context; + SyntaxTree.procedure_call add_proccall = new SyntaxTree.procedure_call(add_methcall); + add_proccall.source_context = _assign.source_context; + return add_proccall; + } + private SyntaxTree.procedure_call ConvertOperatorToProcedureCall(SyntaxTree.assign _assign) + { + SyntaxTree.ident operator_name = new PascalABCCompiler.SyntaxTree.ident(name_reflector.get_name(_assign.operator_type)); + operator_name.source_context = _assign.to.source_context; + SyntaxTree.dot_node dot = new PascalABCCompiler.SyntaxTree.dot_node(_assign.to, operator_name); + dot.source_context = _assign.to.source_context; + SyntaxTree.expression_list exprlist = new SyntaxTree.expression_list(); + exprlist.expressions.Add(_assign.from); + exprlist.source_context = _assign.to.source_context; + SyntaxTree.method_call add_methcall = new SyntaxTree.method_call(exprlist); + add_methcall.dereferencing_value = dot; + add_methcall.source_context = _assign.source_context; + SyntaxTree.procedure_call add_proccall = new SyntaxTree.procedure_call(add_methcall); + add_proccall.source_context = _assign.source_context; + return add_proccall; + } + + private expression_node ConstructDecExpr(expression_node en, location loc) + { + int_const_node one = new int_const_node(1, loc); + return find_operator(SyntaxTree.Operators.Minus, en, one, loc); + } + + private void check_field_reference_for_assign(class_field_reference expr, location loc) + { + if (expr.obj is namespace_constant_reference || expr.obj is function_constant_reference) + AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); + else if (expr.obj is class_field_reference) check_field_reference_for_assign(expr.obj as class_field_reference,loc); + else if (expr.obj is simple_array_indexing) check_expression_for_assign((expr.obj as simple_array_indexing).simple_arr_expr,loc); + } + + private void check_expression_for_assign(expression_node expr, location loc) + { + if (expr is namespace_constant_reference || expr is function_constant_reference) + AddError(loc, "LEFT_SIDE_CANNOT_BE_ASSIGNED_TO"); + else if (expr is class_field_reference) check_field_reference_for_assign(expr as class_field_reference,loc); + else if (expr is simple_array_indexing) check_expression_for_assign((expr as simple_array_indexing).simple_arr_expr,loc); + } + + public override void visit(SyntaxTree.expression _expression) + { + throw new NotSupportedError(get_location(_expression)); + } + + public void visit_statement_list_internal(SyntaxTree.statement_list _statement_list) + { + statements_list stl = new statements_list(get_location(_statement_list), get_location_with_check(_statement_list.left_logical_bracket), get_location_with_check(_statement_list.right_logical_bracket)); + + for (var i = 0; i < _statement_list.subnodes.Count; i++) // SSM 13.10.16 - поменял т.к. собираюсь менять узлы в процессе обхода + { + statement syntax_statement = _statement_list.subnodes[i]; + try + { + statement_node semantic_statement = convert_strong(syntax_statement); + if (semantic_statement != null) + { + if (stl.statements.Count > 0 && stl.statements[0] is basic_function_call && i == 2) + { + base_function_call bfc = stl.statements[0] as basic_function_call; + if (bfc.type != null && bfc.type.name.Contains("<>local_variables_class") && (semantic_statement is compiled_constructor_call || semantic_statement is common_constructor_call) + && !context.converted_func_stack.Empty && context.converted_func_stack.top() is common_method_node && (context.converted_func_stack.top() as common_method_node).is_constructor) + stl.statements.AddElementFirst(semantic_statement); + else + stl.statements.AddElement(semantic_statement); + } + else + stl.statements.AddElement(semantic_statement); + } + context.allow_inherited_ctor_call = false; + } + catch (Errors.Error ex) + { + if (ThrowCompilationError || ex is MemberIsNotDeclaredInType || ex is UndefinedNameReference)//TODO: add interface + throw ex; + else + ErrorsList.Add(ex); + } + } + + return_value(stl); + } + + public override void visit(SyntaxTree.statement_list _statement_list) + { + if (_statement_list.IsInternal) // можно два if поставить перед push и pop здесь!!! + { + visit_statement_list_internal(_statement_list); + return; + } + + #region MikhailoMMX, обработка omp parallel section + bool isGenerateParallel = false; + bool isGenerateSequential = true; + if (OpenMP.SectionsFound) //если в программе есть хоть одна директива parallel sections - проверяем: + if (DirectivesToNodesLinks.ContainsKey(_statement_list) && OpenMP.IsParallelSectionsDirective(DirectivesToNodesLinks[_statement_list])) + { + //перед этим узлом есть директива parallel sections + if (CurrentParallelPosition == ParallelPosition.Outside) //входим в самый внешний параллельный sections + { + var f = _statement_list.DescendantNodes().OfType().FirstOrDefault(); + if (f != null) + AddError(get_location(f), "OPENMP_CONTROLLED_CONSTRUCTIONS_CANNOT_CONTAIN_LAMBDAS"); + //сгенерировать сначала последовательную ветку, затем параллельную + //устанавливаем флаг и продолжаем конвертирование, считая, что конвертируем последовательную ветку + isGenerateParallel = true; + CurrentParallelPosition = ParallelPosition.InsideSequential; + //в конце за счет флага вернем состояние обратно и сгенерируем и параллельную ветку тоже + } + else //уже генерируем одну из веток + if (CurrentParallelPosition == ParallelPosition.InsideParallel) + { + isGenerateParallel = true; + isGenerateSequential = false; + } + //else + //флаг isGenerateParallel не установлен, параллельная ветка не сгенерируется + } + #endregion + + + statements_list stl = new statements_list(get_location(_statement_list), get_location_with_check(_statement_list.left_logical_bracket), get_location_with_check(_statement_list.right_logical_bracket)); + convertion_data_and_alghoritms.statement_list_stack_push(stl); + for (var i = 0; i < _statement_list.subnodes.Count; i++) // SSM 13.10.16 - поменял т.к. собираюсь менять узлы в процессе обхода + { + statement syntax_statement = _statement_list.subnodes[i]; + try + { + statement_node semantic_statement = convert_strong(syntax_statement); + if (semantic_statement != null) + { + if (stl.statements.Count > 0 && stl.statements[0] is basic_function_call && i == 2) + { + base_function_call bfc = stl.statements[0] as basic_function_call; + if (bfc.type != null && bfc.type.name.Contains("<>local_variables_class") && + (semantic_statement is compiled_constructor_call && !(semantic_statement as compiled_constructor_call).new_obj_awaited() || semantic_statement is common_constructor_call && !(semantic_statement as common_constructor_call).new_obj_awaited()) + && !context.converted_func_stack.Empty && context.converted_func_stack.top() is common_method_node && (context.converted_func_stack.top() as common_method_node).is_constructor) + stl.statements.AddElementFirst(semantic_statement); + else + stl.statements.AddElement(semantic_statement); + } + else + stl.statements.AddElement(semantic_statement); + } + context.allow_inherited_ctor_call = false; + } + catch (Errors.Error ex) + { + if (ex is CompilationErrorWithLocation && (ex as CompilationErrorWithLocation).loc == null) + (ex as CompilationErrorWithLocation).loc = get_location(syntax_statement); + if (ThrowCompilationError || ex is MemberIsNotDeclaredInType || ex is UndefinedNameReference)//TODO: add interface + throw ex; + else + ErrorsList.Add(ex); + } + } + convertion_data_and_alghoritms.statement_list_stack.pop(); + + #region MikhailoMMX, обработка omp parallel sections + //флаг был установлен только если это самый внешний parallel sections и нужно сгенерировать обе ветки + //или если это вложенный parallel sections, нужно сгенерировать обе ветки, но без проверки на OMP_Available + //Последовательная ветка только что сгенерирована, теперь меняем состояние и генерируем параллельную + if (isGenerateParallel) + { + CurrentParallelPosition = ParallelPosition.InsideParallel; + statements_list omp_stl = OpenMP.TryConvertSections(stl, _statement_list, this); + CurrentParallelPosition = ParallelPosition.Outside; + if (omp_stl != null) + { + return_value(omp_stl); + return; + } + } + #endregion + + return_value(stl); + } + + public override void visit(SyntaxTree.syntax_tree_node _tree_node) + { + throw new NotSupportedError(get_location(_tree_node)); + } + + private bool has_dll_import_attribute(common_function_node cfn) + { + foreach (attribute_node attr in cfn.attributes) + { + if (attr.attribute_type == SystemLibrary.SystemLibrary.dllimport_type) + return true; + } + return false; + } + + private bool is_pinvoke(SyntaxTree.proc_block bl) + { + if (bl is SyntaxTree.external_directive) + { + return true; + } + return false; + } + + private attribute_node get_dll_import_attribute(common_function_node cfn) + { + foreach (attribute_node attr in cfn.attributes) + { + if (attr.attribute_type == SystemLibrary.SystemLibrary.dllimport_type) + return attr; + } + return null; + } + + public override void visit(SyntaxTree.external_directive _external_directive) + { + string module_name = ""; + string name = ""; + if (context.converted_func_stack.size > 1) + AddError(context.top_function.loc, "EXTERNAL_METHOD_CANNOT_BE_NESTED"); + if (context.converted_func_stack.top() is common_method_node && (context.converted_func_stack.top() as common_method_node).polymorphic_state != SemanticTree.polymorphic_state.ps_static) + AddError(context.top_function.loc, "EXTERNAL_METHOD_SHOULD_BE_STATIC"); + if (context.converted_func_stack.top().is_generic_function) + AddError(context.top_function.loc, "EXTERNAL_METHOD_CANNOT_BE_GENERIC"); + if (context.converted_func_stack.top() is common_method_node && (context.converted_func_stack.top() as common_method_node).common_comprehensive_type.is_generic_type_definition) + AddError(context.top_function.loc, "EXTERNAL_METHOD_CANNOT_BE_DECLARED_IN_GENERIC_TYPE"); + + if (_external_directive.modulename == null) + { + if (!has_dll_import_attribute(context.top_function)) + { + AddError(context.top_function.loc, "FUNCTION_MUST_HAVE_DLLIMPORT_ATTRIBUTE"); + } + else + { + location loc2 = get_location(_external_directive); + pinvoke_statement pinv_stmt = new pinvoke_statement(loc2); + //statement_node_list sal = new statement_node_list(loc); + //sal.AddElement(ext_stmt); + statements_list sl2 = new statements_list(loc2); + sl2.statements.AddElement(pinv_stmt); + //return_value(sl); + context.code = sl2; + return; + } + } + if (has_dll_import_attribute(context.top_function)) + { + AddError(get_location(_external_directive.modulename), "FUNCTION_MUST_HAVE_ONLY_EXTERNAL_STATEMENT"); + } + if (_external_directive.modulename is SyntaxTree.string_const) + { + module_name = ((SyntaxTree.string_const)_external_directive.modulename).Value; + } + else if (_external_directive.modulename is SyntaxTree.ident) + { + //throw new CompilerInternalError("Unsupported now"); + //throw new NotSupportedError(get_location(_external_directive)); + expression_node en = convert_strong(_external_directive.modulename as SyntaxTree.ident); + if (en is string_const_node) + module_name = (en as string_const_node).constant_value; + else + AddError(get_location(_external_directive.modulename), "STRING_CONSTANT_EXPECTED"); + } + else + AddError(get_location(_external_directive.modulename), "STRING_CONSTANT_OR_IDENTIFIER_EXPECTED"); + if (_external_directive.name == null) + { + name = context.converted_func_stack.top().name; + } + else + if (_external_directive.name is SyntaxTree.string_const) + { + name = ((SyntaxTree.string_const)_external_directive.name).Value; + } + else if (_external_directive.name is SyntaxTree.ident) + { + expression_node en = convert_strong(_external_directive.name as SyntaxTree.ident); + if (en is string_const_node) + name = (en as string_const_node).constant_value; + else + AddError(get_location(_external_directive.name), "STRING_CONSTANT_EXPECTED"); + } + else + { + //throw new CompilerInternalError("Unsupported now"); + AddError(get_location(_external_directive.name), "STRING_CONSTANT_OR_IDENTIFIER_EXPECTED"); + } + location loc = get_location(_external_directive); + external_statement ext_stmt = new external_statement(module_name, name, loc); + //statement_node_list sal = new statement_node_list(loc); + //sal.AddElement(ext_stmt); + statements_list sl = new statements_list(loc); + sl.statements.AddElement(ext_stmt); + //return_value(sl); + context.code = sl; + } + + public override void visit(SyntaxTree.unit_or_namespace _name_space) + { + throw new NotSupportedError(get_location(_name_space)); + } + + public override void visit(SyntaxTree.using_list _using_list) + { + throw new NotSupportedError(get_location(_using_list)); + } + + public override void visit(SyntaxTree.jump_stmt _return_stmt) + { + if (_return_stmt.JumpType != PascalABCCompiler.SyntaxTree.JumpStmtType.Return) + { + throw new NotSupportedError(get_location(_return_stmt)); + } + if (_return_stmt.expr == null) + { + if (context.top_function.return_value_type != null && context.top_function.return_value_type != SystemLibrary.SystemLibrary.void_type) + { + AddError(get_location(_return_stmt), "FUNCTION_SHOULD_RETURN_VALUE"); + ret.return_value(new empty_statement(null)); + return; + } + ret.return_value(new return_node(null, null)); + } + else + { + type_node rettype = context.top_function.return_value_type; + if (rettype == null || rettype == SystemLibrary.SystemLibrary.void_type) + { + AddError(get_location(_return_stmt.expr), "FUNCTION_SHOULD_NOT_RETURN_VALUE"); + ret.return_value(new empty_statement(null)); + return; + } + expression_node en = convert_strong(_return_stmt.expr); + en = convertion_data_and_alghoritms.convert_type(en, rettype); + ret.return_value(new return_node(en, get_location(_return_stmt.expr))); + } + } + + public override void visit(SyntaxTree.loop_stmt _loop_stmt) + { + throw new NotSupportedError(get_location(_loop_stmt)); + } + + private bool IsGetEnumerator(type_node tn, ref type_node elem_type) + { + if (tn == null || tn is null_type_node || tn.ImplementingInterfaces == null) return false; + compiled_type_node ctn = compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(compiler_string_consts.IEnumerableInterfaceName)); + if (tn == ctn) + return true; + foreach (SemanticTree.ITypeNode itn in tn.ImplementingInterfaces) + { + if (itn == ctn) + { + elem_type = tn.element_type; + if (elem_type != null) return true; + function_node get_enumerator_func = null; + List sil = ctn.find_in_type(compiler_string_consts.GetEnumeratorMethodName); + if(sil != null) + foreach(SymbolInfo si in sil) + { + if (get_enumerator_func != null) + break; + get_enumerator_func = si.sym_info as function_node; + if (get_enumerator_func.parameters.Count == 0) + break; + get_enumerator_func = null; + } + elem_type = (get_enumerator_func.return_value_type.find_first_in_type(compiler_string_consts.CurrentPropertyName).sym_info as property_node).get_function.return_value_type; + return true; + } + } + return false; + } + + public bool FindIEnumerableElementType(type_node tn, ref type_node elem_type, out bool sys_coll_ienum) + { + sys_coll_ienum = false; + var IEnstring = "System.Collections.IEnumerable"; + compiled_type_node ctn = compiled_type_node.get_type_node(NetHelper.NetHelper.FindType(IEnstring)); + if (tn is compiled_type_node || tn is compiled_generic_instance_type_node) // Если этот тип зашит в .NET + // IEnumerable, Range(1,10), Dictionary: tn = compiled_type_node + // IEnumerable: tn = compiled_generic_instance_type_node + // FibGen = class(IEnumerable,IEnumerator): tn = common_type_node, en = compiled_type_node + // array of Person: tn = common_type_node + { + compiled_type_node orig; + + if (tn is compiled_type_node) + orig = tn as compiled_type_node; + else orig = (tn as compiled_generic_instance_type_node).original_generic as compiled_type_node; + //var pars = tn.instance_params; + System.Type ct = orig.compiled_type; + + Type r; + var IEnTstring = "System.Collections.Generic.IEnumerable`1"; + //if (ct.ToString().StartsWith(IEnTstring)) // SSM Ошибка!!! IEnumerable`1[] тоже начинается с IEnumerable`1, но это массив! + if (ct.Name.Equals("IEnumerable`1")) + r = ct; + else + r = ct.GetInterface(IEnTstring); + if (r != null) + { + Type arg1 = r.GetGenericArguments().First(); // тип параметра IEnumerable + var str = arg1.GetGenericArguments().Count(); + if (tn is compiled_type_node) + { + elem_type = compiled_type_node.get_type_node(arg1); + } + else + { + if (arg1.GetGenericArguments().Count()>0) + { + elem_type = compiled_type_node.get_type_node(arg1.GetGenericTypeDefinition()); + elem_type = elem_type.get_instance(tn.instance_params); // SSM 19/07/15 - работает!!! + } + else + { + var ip = tn.instance_params; + + var IGrTstring = "System.Linq.IGrouping`2"; + if (ct.ToString().StartsWith(IGrTstring)) + elem_type = ip[1]; + else + { + var ln = tn.ImplementingInterfaces; + elem_type = null; + foreach (var x in ln) + { + var xctn = x as compiled_generic_instance_type_node; + if (xctn != null && xctn.name.StartsWith("IEnumerable<")) // Немного грубовато. + { + elem_type = xctn.instance_params[0]; + break; + } + } + if (elem_type == null) + elem_type = ip[0]; + } + + //var Tname = ip[0].name; + //elem_type = convert_strong(new SyntaxTree.named_type_reference(Tname, _foreach_stmt.in_what.source_context)); + } + + //elem_type.instance_params = tn.instance_params; + //var ip = tn.instance_params; + //var Tname = new string(tn.name.SkipWhile(c => c != '<').Skip(1).TakeWhile(c => c != ',' && c != '>').ToArray()); + //var Tname = ip[0].name; + //var Tname = "System.Collections.Generic.KeyValuePair'2"; // + //elem_type = convert_strong(new SyntaxTree.named_type_reference(Tname, _foreach_stmt.in_what.source_context)); + } + return true; + } + else + { + if (tn.element_type != null) // значит, это массив любой размерности - 02.02.16 SSM - еще может быть множество set of T - 22.02.16 SSM + { + elem_type = tn.element_type; + return true; + } + + var ttt = tn.ImplementingInterfaces; + foreach (SemanticTree.ITypeNode itn in tn.ImplementingInterfaces) + { + if (itn == ctn) + { + elem_type = SystemLibrary.SystemLibrary.object_type; + sys_coll_ienum = true; + return true; + } + } + } + } + /*else if (tn is compiled_generic_instance_type_node) + { + var g = tn as compiled_generic_instance_type_node; + var og = g.original_generic; + var tt = og.ImplementingInterfaces; + if (_foreach_stmt.type_name != null && _foreach_stmt.type_name.GetType()!=typeof(SyntaxTree.no_type_foreach)) + elem_type = convert_strong(_foreach_stmt.type_name); + else + { + var fn = tn.full_name; + } + return true; + } */ + else // если мы самостоятельно определяем этот тип - можно реализовать в PascalABC.NET только IEnumerable. // Сейчас уже можно!!!!! + // Попытка реализовать IEnumerable натыкается на необходимость определять GetEnumerator, возвращающий IEnumerator и IEnumerator + { + if (tn == null || tn is null_type_node || tn.ImplementingInterfaces == null) + { + if (tn != null && tn.base_type != null) + return FindIEnumerableElementType(tn.base_type, ref elem_type, out sys_coll_ienum); + return false; + } + + if (tn.element_type != null && tn.type_special_kind != SemanticTree.type_special_kind.typed_file) // еще может быть множество set of T - 22.02.16 SSM + { + elem_type = tn.element_type; + return true; + } + + foreach (SemanticTree.ITypeNode itn in tn.ImplementingInterfaces) // Ищем интерфейс IEnumerable и возвращаем T в качестве elem_type + { + if (itn is compiled_generic_instance_type_node) + { + var itnc = (itn as compiled_generic_instance_type_node); + var tt = (itnc.original_generic as compiled_type_node).compiled_type; + if (tt == typeof(System.Collections.Generic.IEnumerable<>)) + { + elem_type = itnc.generic_parameters[0] as common_type_node; + return true; + } + } + } + + foreach (SemanticTree.ITypeNode itn in tn.ImplementingInterfaces) // если не нашли - ищем интерфейс IEnumerable и возвращаем object в качестве elem_type + { + if (itn is compiled_type_node) // Именно этот кусок отвечает за IEnumerable и мы его закомментировали + { + var itnc = (itn as compiled_type_node).compiled_type; /* SSM раскомментировал 15.05.2020 - пришла пора*/ + if (itnc.IsGenericType) + { + var my = itnc.GetGenericTypeDefinition();// = typeof(System.Collections.Generic.IEnumerable<>) + if (my == typeof(System.Collections.Generic.IEnumerable<>)) + { + var aarg1 = itnc.GetGenericArguments().First(); + elem_type = compiled_type_node.get_type_node(aarg1); + return true; + } + } + else /* end SSM раскомментировал 15.05.2020 - пришла пора*/ + if (itn == ctn) + { + elem_type = SystemLibrary.SystemLibrary.object_type; + sys_coll_ienum = true; + return true; + } + } + } + } + if (tn != null && tn.base_type != null) + return FindIEnumerableElementType(tn.base_type, ref elem_type, out sys_coll_ienum); + return false; + } + + private int GenIdNum = 0; + public ident GenIdentName() + { + GenIdNum++; + return new ident("$GenId" + GenIdNum.ToString()); + } + + public override void visit(SyntaxTree.addressed_value_funcname _addressed_value_funcname) + { + throw new NotSupportedError(get_location(_addressed_value_funcname)); + } + + public override void visit(SyntaxTree.named_type_reference_list _named_type_reference_list) + { + throw new NotSupportedError(get_location(_named_type_reference_list)); + } + + public override void visit(SyntaxTree.template_param_list _template_param_list) + { + throw new NotSupportedError(get_location(_template_param_list)); + } + + public override void visit(double_question_node node) + { + expression_node condition = convert_strong(node.left); + + convertion_data_and_alghoritms.convert_type(new null_const_node(null_type_node.get_type_node(), condition.location), condition.type); + expression_node left = condition; + expression_node right = convert_strong(node.right); + if (condition is null_const_node) + convertion_data_and_alghoritms.convert_type(new null_const_node(null_type_node.get_type_node(), right.location), right.type); + + try_convert_typed_expression_to_function_call(ref left); + try_convert_typed_expression_to_function_call(ref right); + + if (left is null_const_node && right.type.is_value_type) + { + if (right.type is compiled_type_node) + { + var rt = right.type as compiled_type_node; + if (!rt.compiled_type.IsGenericType || rt.compiled_type.GetGenericTypeDefinition() != typeof(System.Nullable<>)) + { + right = convert_strong(ToNullable(node.right)); + } + } + } + else + if (right is null_const_node && left.type.is_value_type) + { + if (left.type is compiled_type_node) + { + var lt = left.type as compiled_type_node; + if (!lt.compiled_type.IsGenericType || lt.compiled_type.GetGenericTypeDefinition() != typeof(System.Nullable<>)) + { + left = convert_strong(ToNullable(node.left)); + } + } + } + + /*var typeComparisonResult = type_table.compare_types(left.type, right.type); + if (typeComparisonResult == type_compare.greater_type) + right = convertion_data_and_alghoritms.convert_type(right, left.type); + else left = convertion_data_and_alghoritms.convert_type(left, right.type);*/ + if (left is null_const_node) + { + left = convertion_data_and_alghoritms.convert_type(left, right.type); + } + else + { + delegated_methods del_left = left.type as delegated_methods; + delegated_methods del_right = right.type as delegated_methods; + if (del_left != null && del_right != null && del_left.empty_param_method == null && del_right.empty_param_method == null) + { + base_function_call bfc = del_left.proper_methods[0]; + common_type_node del = + convertion_data_and_alghoritms.type_constructor.create_delegate(context.get_delegate_type_name(), bfc.simple_function_node.return_value_type, bfc.simple_function_node.parameters, context.converted_namespace, null); + context.converted_namespace.types.AddElement(del); + right = convertion_data_and_alghoritms.explicit_convert_type(right, del); + left = convertion_data_and_alghoritms.explicit_convert_type(left, del); + } + else + { + var rtl = type_table.get_convertions(right.type, left.type); + var ltr = type_table.get_convertions(left.type, right.type); + + if (ltr.first != null && rtl.first == null) + { + left = convertion_data_and_alghoritms.convert_type(left, right.type); + } + else if (ltr.first == null && rtl.first != null) + { + right = convertion_data_and_alghoritms.convert_type(right, left.type); + } + else + { + // если оба типа - целые + if (convertion_data_and_alghoritms.is_value_int_type(left.type) && convertion_data_and_alghoritms.is_value_int_type(right.type)) + { + var lub = convertion_data_and_alghoritms.least_upper_bound_value_int_type(left.type, right.type); + if (lub == left.type) + right = convertion_data_and_alghoritms.convert_type(right, left.type); + else if (lub == right.type) + left = convertion_data_and_alghoritms.convert_type(left, right.type); + else + { + right = convertion_data_and_alghoritms.convert_type(right, lub); + left = convertion_data_and_alghoritms.convert_type(right, lub); + } + } + else if (left.type == SystemLibrary.SystemLibrary.float_type && right.type == SystemLibrary.SystemLibrary.double_type) + left = convertion_data_and_alghoritms.convert_type(left, right.type); + else if (right.type == SystemLibrary.SystemLibrary.float_type && left.type == SystemLibrary.SystemLibrary.double_type) + right = convertion_data_and_alghoritms.convert_type(right, left.type); + else if (left.type == right.type) + { } + else // Это было - для совместимости. Что-то может не учтено + { + right = convertion_data_and_alghoritms.convert_type(right, left.type); + } + + } + + } + + } + + + //right = convertion_data_and_alghoritms.convert_type(right, left.type); + return_value(new double_question_colon_expression(condition, right, get_location(node))); + } + + public override void visit(SyntaxTree.question_colon_expression node) + { + expression_node condition = convert_strong(node.condition); + condition = convertion_data_and_alghoritms.convert_type(condition, SystemLibrary.SystemLibrary.bool_type); + expression_node left = convert_strong(node.ret_if_true); + expression_node right = convert_strong(node.ret_if_false); + + try_convert_typed_expression_to_function_call(ref left); + try_convert_typed_expression_to_function_call(ref right); + + if (left is null_const_node && right.type.is_value_type) + { + if (right.type is compiled_type_node) + { + var rt = right.type as compiled_type_node; + if (!rt.compiled_type.IsGenericType || rt.compiled_type.GetGenericTypeDefinition() != typeof(System.Nullable<>)) + { + right = convert_strong(ToNullable(node.ret_if_false)); + } + } + } + else + if (right is null_const_node && left.type.is_value_type) + { + if (left.type is compiled_type_node) + { + var lt = left.type as compiled_type_node; + if (!lt.compiled_type.IsGenericType || lt.compiled_type.GetGenericTypeDefinition() != typeof(System.Nullable<>)) + { + left = convert_strong(ToNullable(node.ret_if_true)); + } + } + } + + /*var typeComparisonResult = type_table.compare_types(left.type, right.type); + if (typeComparisonResult == type_compare.greater_type) + right = convertion_data_and_alghoritms.convert_type(right, left.type); + else left = convertion_data_and_alghoritms.convert_type(left, right.type);*/ + if (left is null_const_node) + { + left = convertion_data_and_alghoritms.convert_type(left, right.type); + } + else + { + delegated_methods del_left = left.type as delegated_methods; + delegated_methods del_right = right.type as delegated_methods; + if (del_left != null && del_right != null && del_left.empty_param_method == null && del_right.empty_param_method == null) + { + base_function_call bfc = del_left.proper_methods[0]; + common_type_node del = + convertion_data_and_alghoritms.type_constructor.create_delegate(context.get_delegate_type_name(), bfc.simple_function_node.return_value_type, bfc.simple_function_node.parameters, context.converted_namespace, null); + context.converted_namespace.types.AddElement(del); + right = convertion_data_and_alghoritms.explicit_convert_type(right, del); + left = convertion_data_and_alghoritms.explicit_convert_type(left, del); + } + else + { + var rtl = type_table.get_convertions(right.type, left.type); + var ltr = type_table.get_convertions(left.type, right.type); + + if (ltr.first != null && rtl.first == null) + { + left = convertion_data_and_alghoritms.convert_type(left, right.type); + } + else if (ltr.first == null && rtl.first != null) + { + right = convertion_data_and_alghoritms.convert_type(right, left.type); + } + else + { + // если оба типа - целые + if (convertion_data_and_alghoritms.is_value_int_type(left.type) && convertion_data_and_alghoritms.is_value_int_type(right.type)) + { + var lub = convertion_data_and_alghoritms.least_upper_bound_value_int_type(left.type, right.type); + if (lub == left.type) + right = convertion_data_and_alghoritms.convert_type(right, left.type); + else if (lub == right.type) + left = convertion_data_and_alghoritms.convert_type(left, right.type); + else + { + right = convertion_data_and_alghoritms.convert_type(right, lub); + left = convertion_data_and_alghoritms.convert_type(right, lub); + } + } + else if (left.type == SystemLibrary.SystemLibrary.float_type && right.type == SystemLibrary.SystemLibrary.double_type) + left = convertion_data_and_alghoritms.convert_type(left, right.type); + else if (right.type == SystemLibrary.SystemLibrary.float_type && left.type == SystemLibrary.SystemLibrary.double_type) + right = convertion_data_and_alghoritms.convert_type(right, left.type); + else if (left.type == right.type) + { } + else // Это было - для совместимости. Что-то может не учтено + { + right = convertion_data_and_alghoritms.convert_type(right, left.type); + } + + } + + } + + } + + + //right = convertion_data_and_alghoritms.convert_type(right, left.type); + return_value(new question_colon_expression(condition, left, right, get_location(node))); + } + + Dictionary delegate_cache = new Dictionary(); + + public List visit_type_list(List types) + { + List tparams = new List(); + foreach (SyntaxTree.type_definition id in types) + { + type_node tn = null; + if ((id is function_header || id is procedure_header) && delegate_cache.ContainsKey(id)) + tn = delegate_cache[id]; + else + tn = convert_strong(id); + + if (tn == null) + { + AddError(get_location(id), "TYPE_NAME_EXPECTED"); + } + if ((id is function_header || id is procedure_header) && !delegate_cache.ContainsKey(id)) + { + delegate_cache[id] = tn; + } + tparams.Add(tn); + } + return tparams; + } + + public List visit_type_list_with_check(List types, List gpe_list, bool where_checking) + { + List tparams = new List(); + foreach (SyntaxTree.type_definition id in types) + { + type_node tn = convert_strong(id); + CompilationErrorWithLocation not_useful = generic_parameter_eliminations.check_type_generic_useful(tn, get_location(id)); + if (not_useful != null) + { + AddError(not_useful); + } + tparams.Add(tn); + } + //Проверяем типы на соответствие ограничениям + int i; + if (where_checking) + { + CompilationErrorWithLocation err = generic_parameter_eliminations.check_type_list(tparams, gpe_list, false, out i); + if (err != null) + { + err.loc = get_location(types[i]); + AddError(err); + } + } + return tparams; + } + + public type_node get_generic_instance(SymbolInfo si, List type_pars) + { + type_node node = si.sym_info as type_node; + compiled_type_node comp_node = node as compiled_type_node; + List lgpe = null; + if (!context.skip_check_where_sections) + { + lgpe = (comp_node == null) ? + (node as common_type_node).parameters_eliminations : + comp_node.parameters_eliminations; + } + List tparams = visit_type_list_with_check(type_pars, lgpe, !context.skip_check_where_sections); + return node.get_instance(tparams); + } + + public SymbolInfo ConvertTypeToInstance(SymbolInfo si, List type_pars, location loc) + { + if (si == null) + return null; + template_class tclass = si.sym_info as template_class; + if (tclass == null) + { + generic_indicator gi = si.sym_info as generic_indicator; + if (gi != null) + { + AddError(loc, "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", gi.generic.name, gi.generic.generic_params.Count); + } + return null; + } + //Формируем список параметров инстанцирования + List tparams = visit_type_list(type_pars); + + type_node t = instance_any(tclass, tparams, loc); + return new SymbolInfo(t); + } + + public override void visit(SyntaxTree.template_type_reference _template_type_reference) + { + int last_num = _template_type_reference.name.names.Count; + string typename = _template_type_reference.name.names[last_num - 1].name; + location loc = get_location(_template_type_reference); + List sil; + List tparams; + + //Обрабатываем generic-типы + int tcount = _template_type_reference.params_list.params_list.Count; + string temp_name = _template_type_reference.name.names[last_num - 1].name; + if (!_template_type_reference.name.names[last_num - 1].name.Contains(compiler_string_consts.generic_params_infix)) // SSM 26.03.14 + _template_type_reference.name.names[last_num - 1].name += compiler_string_consts.generic_params_infix + tcount; + sil = context.find_definition_node(_template_type_reference.name, loc); + if (sil != null) + { + type_node rez_type = sil?.FirstOrDefault().sym_info as type_node; + foreach (type_definition td in _template_type_reference.params_list.params_list) + if (td is named_type_reference && (td as named_type_reference).names.Count > 0 && (td as named_type_reference).names[0].name == "") + { + return_value(rez_type); + return; + } + rez_type = get_generic_instance(sil?.FirstOrDefault(), _template_type_reference.params_list.params_list); + if (context.skip_check_where_sections) + { + generic_instance_type_node gitn = rez_type as generic_instance_type_node; + if (gitn != null) + { + context.possible_incorrect_instances.Add( + new type_instance_and_location(gitn, loc)); + } + } + return_value(rez_type); + return; + } + _template_type_reference.name.names[last_num - 1].name = temp_name; + sil = context.find_definition_node(_template_type_reference.name, loc); + if (sil == null) + { + check_possible_generic_names(_template_type_reference.name, loc); + AddError(new UndefinedNameReference(typename, loc)); + } + template_class tclass = sil.FirstOrDefault().sym_info as template_class; + if (tclass == null) + { + generic_indicator gi = sil.FirstOrDefault().sym_info as generic_indicator; + if (gi != null) + { + AddError(get_location(_template_type_reference), "TYPE_{0}_HAS_{1}_GENERIC_PARAMETERS", typename, gi.generic.generic_params.Count); + } + AddError(get_location(_template_type_reference), "{0}_IS_NOT_TEMPLATE_CLASS", typename); + } + foreach (type_definition td in _template_type_reference.params_list.params_list) + if (td is named_type_reference && (td as named_type_reference).names.Count > 0 && (td as named_type_reference).names[0].name == "") + { + if (tclass.type_dec.type_def is template_type_reference) + { + template_type_reference ttr = new template_type_reference((tclass.type_dec.type_def as template_type_reference).name, _template_type_reference.params_list, _template_type_reference.source_context); + ttr.names = (tclass.type_dec.type_def as template_type_reference).names; + if (ttr.name.names.Count >= 1 && ttr.name.names[ttr.name.names.Count - 1].name.IndexOf('`') != -1) + ttr.name.names[ttr.name.names.Count - 1].name = ttr.name.names[ttr.name.names.Count - 1].name.Substring(0, ttr.name.names[ttr.name.names.Count - 1].name.IndexOf('`')); + + return_value(convert_strong(ttr)); + return; + } + else if (tclass.type_dec.type_def is named_type_reference) + { + return_value(convert_strong(tclass.type_dec.type_def)); + return; + } + } + //Формируем список параметров инстанцирования + tparams = visit_type_list(_template_type_reference.params_list.params_list); + + type_node t = instance_any(tclass, tparams, get_location(_template_type_reference), _template_type_reference); + return_value(t); + } + + public type_node instance_any(template_class tc, List template_params, location loc, template_type_reference ttr=null) + { + common_type_node t = instance(tc, template_params, loc, ttr); + if (tc.is_synonym) + { + return t.fields[0].type; + } + return t; + } + + public common_type_node instance(template_class tc, List template_params, location loc, template_type_reference used_ttr = null) + { + //Проверяем, что попытка инстанцирования корректна + SyntaxTree.class_definition cl_def = tc.type_dec.type_def as SyntaxTree.class_definition; + SyntaxTree.template_type_name ttn = tc.type_dec.type_name as SyntaxTree.template_type_name; +#if (DEBUG) + if (!tc.is_synonym) + { + if (cl_def == null) + { + throw new PascalABCCompiler.TreeConverter.CompilerInternalError("No body definition in template class."); + } + if (cl_def.template_args == null || cl_def.template_args.idents == null) + { + throw new PascalABCCompiler.TreeConverter.CompilerInternalError("No template arguments in syntax tree."); + } + } + else + { + if (ttn == null) + { + throw new PascalABCCompiler.TreeConverter.CompilerInternalError("No template name."); + } + } +#endif + List template_formals = (tc.is_synonym) ? + ttn.template_args.idents : cl_def.template_args.idents; + if (template_formals.Count != ttn.template_args.idents.Count) + { + AddError(loc, "TEMPLATE_ARGUMENTS_COUNT_MISMATCH"); + } + + if (!tc.is_synonym) + { + foreach (type_node tnode in template_params) + { + if (depended_from_generic_parameter(tnode)) + { + AddError(loc, "TEMPLATES_AND_GENERICS_ARE_INCOMPATIBLE"); + } + } + } + + //А вдруг такая инстанция уже есть - вернём её + string inst_name = tc.CreateTemplateInstance(template_params, loc); + List sil = tc.cnn.scope.FindOnlyInScope(inst_name); + if (sil != null) + { + return (common_type_node)sil.FirstOrDefault().sym_info; + } + + //Переходим в место описания шаблона + common_namespace_node current_namespace = context.converted_namespace; + context.converted_namespace = tc.cnn; + common_type_node current_type = context.converted_type; + context.converted_type = null; + template_class current_template = context.converted_template_type; + context.converted_template_type = null; + compiled_type_node current_compiled_type = context.converted_compiled_type; + context.converted_compiled_type = null; + common_function_node_stack current_funk_stack = context.converted_func_stack; + context.converted_func_stack = new common_function_node_stack(); //Думаю, это будет работать + + //DarkStar + statement_list_stack statement_list_stack = convertion_data_and_alghoritms.statement_list_stack; + convertion_data_and_alghoritms.statement_list_stack = new statement_list_stack(); + + bool current_cur_meth_not_in_class = current_converted_method_not_in_class_defined; + current_converted_method_not_in_class_defined = false; + SymbolInfo current_last_created_function = context.last_created_function; + context.last_created_function = null; + bool current_record_created = _record_created; + _record_created = false; + SemanticTree.field_access_level current_fal = context.get_field_access_level(); + document current_doc = current_document; + current_document = tc.cur_document; + bool current_body_exists = body_exists; + body_exists = false; + bool current_allow_inherited_ctor_call = context.allow_inherited_ctor_call; + bool current_is_direct_type_decl = is_direct_type_decl; + is_direct_type_decl = false; + context.allow_inherited_ctor_call = false; + bool current_type_section_converting = type_section_converting; + type_section_converting = true; + SemanticTree.field_access_level curr_fal = context.get_field_access_level(); + List current_var_defs = context.var_defs; + context.var_defs = new List(); + Hashtable current_member_decls = context.member_decls; + context.member_decls = new Hashtable(); + //подменяем using-список + using_namespace_list current_using_list = new using_namespace_list(); + foreach (using_namespace un in using_list) + { + current_using_list.AddElement(un); + } + using_list.clear(); + foreach (using_namespace un in tc.using_list) + { + using_list.AddElement(un); + } + context.converted_type = null; + context.enter_code_block_without_bind(); + + common_type_node ctn; + + bool interface_creating = false; + + //Создаём инстанцию шаблона + if (tc.is_synonym) + { + ctn = context.create_type(inst_name, get_location(ttn)); + } + else + { + if (cl_def.keyword == SyntaxTree.class_keyword.Record) + { + ctn = context.create_record_type(get_location(tc.type_dec.type_name), inst_name); + } + else + { + interface_creating = (cl_def.keyword == PascalABCCompiler.SyntaxTree.class_keyword.Interface); + ctn = context.advanced_create_type(inst_name, get_location(tc.type_dec.type_name), interface_creating); + } + } + ctn.original_template = tc; + bool indefinite = false; + foreach (type_node tn in template_params) + { + indefinite = indefinite || tn.depended_from_indefinite; + } + ctn.SetDependedFromIndefinite(indefinite); + tc.instance_params.Add(ctn, template_params); + + //Ставим в соответствие формальным параметрам шаблона фактические + for (int i = 0; i < template_params.Count; i++) + { + ctn.Scope.AddSymbol(template_formals[i].name, new SymbolInfo(template_params[i])); + } + + //Разбор тела класса + if (tc.is_synonym) + { + Dictionary saved_sc_dict = new Dictionary(); + saved_sc_dict.Add(tc.type_dec.type_def, tc.type_dec.type_def.source_context); + tc.type_dec.type_def.source_context = loc; + + if (tc.type_dec.type_def is template_type_reference) + { + template_type_reference ttr = tc.type_dec.type_def as template_type_reference; + for (int i = 0; i < ttr.params_list.params_list.Count; i++) + { + var prm = ttr.params_list.params_list[i]; + saved_sc_dict.Add(prm, prm.source_context); + if (used_ttr != null && i < used_ttr.params_list.params_list.Count) + prm.source_context = used_ttr.params_list.params_list[i].source_context; + else + prm.source_context = loc; + } + } + type_node synonym_value = convert_strong(tc.type_dec.type_def); + foreach (type_definition td in saved_sc_dict.Keys) + td.source_context = saved_sc_dict[td]; + ctn.fields.AddElement(new class_field(compiler_string_consts.synonym_value_name, + synonym_value, ctn, PascalABCCompiler.SemanticTree.polymorphic_state.ps_static, + PascalABCCompiler.SemanticTree.field_access_level.fal_public, null)); + } + else + { + if (cl_def.keyword == SyntaxTree.class_keyword.Record) + { + _record_created = true; + } + + bool tmp_direct = is_direct_type_decl; + is_direct_type_decl = true; + hard_node_test_and_visit(cl_def); + is_direct_type_decl = tmp_direct; + + //Разбор методов, описанных вне класса + if (!interface_creating) + { + type_section_converting = false; + foreach (procedure_definition_info pdi in tc.external_methods) + { + if (context.converted_namespace != pdi.nspace) + { + context.converted_namespace = pdi.nspace; + using_namespace_list ulist = + (pdi.nspace == tc.cnn) ? tc.using_list : tc.using_list2; + using_list.clear(); + foreach (using_namespace un in ulist) + { + using_list.AddElement(un); + } + template_class.AddUsingListToScope(context.converted_namespace.scope, ulist); + } + + //Заменяем в дереве метода имя шаблонного класса на имя инстанции + string tmp_name = pdi.proc.proc_header.name.class_name.name; + pdi.proc.proc_header.name.class_name.name = inst_name; + + hard_node_test_and_visit(pdi.proc); + + //Обратная замена + pdi.proc.proc_header.name.class_name.name = tmp_name; + } + + foreach (common_method_node cmn in ctn.methods) + { + if (cmn.function_code == null) + { + //AddError(cmn.loc, "FUNCTION_PREDEFINITION_WITHOUT_DEFINITION"); + AddError(new FunctionPredefinitionWithoutDefinition(cmn, cmn.loc)); + } + } + } + } + + //Прыжок обратно + context.leave_code_block(); + context.converted_namespace = current_namespace; + context.converted_type = current_type; + context.converted_template_type = current_template; + context.set_field_access_level(current_fal); + context.converted_func_stack = current_funk_stack; + context.converted_compiled_type = current_compiled_type; + convertion_data_and_alghoritms.statement_list_stack = statement_list_stack; + current_document = current_doc; + body_exists = current_body_exists; + _record_created = current_record_created; + context.last_created_function = current_last_created_function; + is_direct_type_decl = current_is_direct_type_decl; + context.allow_inherited_ctor_call = current_allow_inherited_ctor_call; + current_converted_method_not_in_class_defined = current_cur_meth_not_in_class; + context.set_field_access_level(curr_fal); + type_section_converting = current_type_section_converting; + context.member_decls = current_member_decls; + context.var_defs = current_var_defs; + using_list.clear(); + foreach (using_namespace un in current_using_list) + { + using_list.AddElement(un); + } + + return ctn; + } + + private SyntaxTree.addressed_value convert_named_type_reference_to_addressed_value(SyntaxTree.named_type_reference ntr) + { + SyntaxTree.addressed_value adrv = ntr.names[0]; + for (int i = 1; i < ntr.names.Count; i++) + adrv = new SyntaxTree.dot_node(adrv, ntr.names[i]); + return adrv; + } + + private base_function_call create_constructor_call(type_node tn, expressions_list exprs, location loc, Tuple> lambdas_info = null) + { + if (tn.IsInterface) + { + AddError(loc, "INTERFACE_{0}_CONSTRUCTOR_CALL", tn.name); + } + if (tn.IsStatic) + { + AddError(loc, "STATIC_CONSTRUCTOR_CALL"); + } + if (tn.IsAbstract) + { + AddError(loc, "ABSTRACT_CONSTRUCTOR_{0}_CALL", tn.name); + } + List sil = tn.find_in_type(TreeConverter.compiler_string_consts.default_constructor_name, context.CurrentScope); //tn.Scope); + delete_inherited_constructors(ref sil, tn); + if (sil == null) + AddError(loc, "CONSTRUCTOR_NOT_FOUND"); + function_node fnn = null; + try + { + #region Если встретились лямбды в фактических параметрах, то выбираем нужную функцию из перегруженных, выводим типы, отмечаем флаг в лямбдах, говорящий о том, что мы их реально обходим + //lroman// + if (lambdas_info != null && lambdas_info.Item1) + { + LambdaHelper.processingLambdaParametersForTypeInference++; + var syntax_nodes_parameters = lambdas_info.Item2; + + // SSM 21.05.14 - попытка обработать перегруженные функции с параметрами-лямбдами с различными возвращаемыми значениями + List spf = null; + try + { + function_node fn = convertion_data_and_alghoritms.select_function(exprs, sil, loc, + syntax_nodes_parameters); + int exprCounter = 0; + foreach (SyntaxTree.expression en in syntax_nodes_parameters) + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + exprCounter++; + continue; + } + else + { + var enLambda = (SyntaxTree.function_lambda_definition)en; + LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type, enLambda, this); + enLambda.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; + exprs[exprCounter] = convert_strong(en); + enLambda.lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; + exprCounter++; + } + } + } + catch (SeveralFunctionsCanBeCalled sf) + { + spf = sf.set_of_possible_functions; + // Возможны несколько перегруженных версий - надо выводить дальше в надежде что какие-то уйдут и останется одна + } + + Exception lastmultex = null; + if (spf != null) // пытаемся инстанцировать одну за другой и ошибки гасим try + { + // exprs - глобальная, поэтому надо копировать + int spfnum = -1; // spfnum - первый номер правильно инстанцированной. Пока -1. Если потом встретился второй, то тоже ошибка + int GoodVersionsCount = 0; + int GoodVersionsCountWithSameResType = 0; + for (int i = 0; i < spf.Count; i++) + { + function_node fn = spf[i]; + try + { + int exprCounter = 0; + expressions_list exprs1 = new expressions_list(); + exprs1.AddRange(exprs); // сделали копию + + foreach (SyntaxTree.expression en in syntax_nodes_parameters) + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + exprCounter++; + continue; + } + else + { + var fld = en as SyntaxTree.function_lambda_definition; + + var lambdaName = fld.lambda_name; //lroman Сохранять имя необходимо + var fl = fld.lambda_visit_mode; + + // запомнили типы параметров лямбды - SSM + object[] realparamstype = new object[fld.formal_parameters.params_list.Count]; + // здесь хранятся выведенные типы лямбд или null если типы явно заданы + for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) + { + var laminftypeK = + fld.formal_parameters.params_list[k].vars_type as + SyntaxTree.lambda_inferred_type; + if (laminftypeK == null) + realparamstype[k] = null; + else realparamstype[k] = laminftypeK.real_type; + } + + // запоминаем реальный тип возвращаемого значения если он не указан явно (это должен быть any_type или null если он указан явно) - он может измениться при следующем вызове, поэтому мы его восстановим + var restype = fld.return_type as SyntaxTree.lambda_inferred_type; + object realrestype = null; + if (restype != null) + realrestype = restype.real_type; + + LambdaHelper.InferTypesFromVarStmt(fn.parameters[exprCounter].type, fld, this); + fld.lambda_visit_mode = LambdaVisitMode.VisitForAdvancedMethodCallProcessing; + //lroman + fld.lambda_name = LambdaHelper.GetAuxiliaryLambdaName(lambdaName); + // поправляю имя. Думаю, назад возвращать не надо. ПРОВЕРИТЬ! + + //contextChanger.SaveContextAndUpToNearestDefSect(); + try + { + exprs1[exprCounter] = convert_strong(en); + + type_node resexprtype = fld.RealSemTypeOfResExpr as type_node; + type_node resformaltype = fld.RealSemTypeOfResult as type_node; + var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность + if (bbb) + { + GoodVersionsCountWithSameResType += 1; + spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. + } + + /*var tt = fn.parameters[exprCounter].type as compiled_type_node; + if (tt != null && tt.compiled_type.FullName.ToLower().StartsWith("system.func")) + { + resformaltype = tt.instance_params[tt.instance_params.Count - 1]; // Последний параметр в записи Func - тип возвращаемого значения + var bbb = resexprtype == resformaltype; // только в одном случае должно быть true - эту версию и надо выбирать. Если в нескольких, то неоднозначность + if (bbb) + { + GoodVersionsCountWithSameResType += 1; + spfnum = i; // здесь запоминаем индекс потому что он точно подойдет. Тогда ниже он запоминаться не будет. + } + }*/ + } + catch + { + throw; + } + finally + { + LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, en as function_lambda_definition); + // восстанавливаем сохраненный тип возвращаемого значения + if (restype != null) + restype.real_type = realrestype; + // восстанавливаем сохраненные типы параметров лямбды, которые не были заданы явно + for (var k = 0; k < fld.formal_parameters.params_list.Count; k++) + { + var laminftypeK = + fld.formal_parameters.params_list[k].vars_type as + SyntaxTree.lambda_inferred_type; + if (laminftypeK != null) + laminftypeK.real_type = realparamstype[k]; + } + + fld.lambda_name = lambdaName; //lroman Восстанавливаем имена + fld.lambda_visit_mode = fl; + } + + //contextChanger.RestoreCurrentContext(); + exprCounter++; + } + } + /*if (spfnum >= 0) // два удачных инстанцирования - плохо. Может, одно - с более близким типом возвращаемого значения, тогда это плохо - надо доделать, но пока так + { + spfnum = -2; + break; + }*/ + + if (GoodVersionsCountWithSameResType == 0) + spfnum = i; // здесь запоминаем индекс только если нет подошедших, совпадающих по типу возвращаемого значения + GoodVersionsCount += 1; + for (int j = 0; j < exprs.Count; j++) // копируем назад если всё хорошо + exprs[j] = exprs1[j]; + } + catch (Exception e) + { + // если сюда попали, значит, не вывели типы в лямбде и надо эту инстанцию пропускать + //contextChanger.RestoreCurrentContext(); + lastmultex = e; + } + } + if (GoodVersionsCount > 1 && GoodVersionsCountWithSameResType != 1) // подошло много, но не было ровно одной с совпадающим типом возвращаемого значения + throw new SeveralFunctionsCanBeCalled(loc, spf); + if (GoodVersionsCount == 0) // было много, но ни одна не подошла из-за лямбд + { + throw lastmultex; + //throw new NoFunctionWithSameArguments(subloc2, false); + } + + var kk = 0; + foreach (SyntaxTree.expression en in syntax_nodes_parameters) + //lroman окончательно подставить типы в лямбды + { + if (!(en is SyntaxTree.function_lambda_definition)) + { + kk++; + continue; + } + else + { + LambdaHelper.InferTypesFromVarStmt(spf[spfnum].parameters[kk].type, + en as SyntaxTree.function_lambda_definition, this); + exprs[kk] = convert_strong(en); + kk++; + } + } + } + // SSM 21.05.14 end + LambdaHelper.processingLambdaParametersForTypeInference--; + + fnn = convertion_data_and_alghoritms.select_function(exprs, sil, loc); + } + //lroman// + #endregion + + else + { + fnn = convertion_data_and_alghoritms.select_function(exprs, sil, loc); + } + } + catch (NoFunctionWithSameParametresNum e) + { + e.is_constructor = true; + throw; + } + return create_static_method_call_with_params(fnn, loc, tn, false, exprs); + } + + private expression_node clip_expression_if_need(expression_node expr, type_node tn) + { + if (!(tn is short_string_type_node) && tn.type_special_kind != SemanticTree.type_special_kind.set_type) + return expr; + if (tn is short_string_type_node) + { + return convertion_data_and_alghoritms.create_simple_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringProcedure.sym_info as function_node,null,convertion_data_and_alghoritms.convert_type(expr,SystemLibrary.SystemLibrary.string_type),new int_const_node((tn as short_string_type_node).Length,null)); + } + else if (tn.type_special_kind == SemanticTree.type_special_kind.set_type && tn.element_type != null) + { + ordinal_type_interface oti = tn.element_type.get_internal_interface(internal_interface_kind.ordinal_interface) as ordinal_type_interface; + if (oti != null) + { + base_function_call cmc = null; + if (SystemLibrary.SystemLibInitializer.ClipFunction.sym_info is common_namespace_function_node) + cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as common_namespace_function_node, null); + else + cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipFunction.sym_info as compiled_function_node, null); + cmc.parameters.AddElement(expr); + cmc.parameters.AddElement(oti.lower_value.get_constant_copy(null)); + cmc.parameters.AddElement(oti.upper_value.get_constant_copy(null)); + cmc.ret_type = tn; + return cmc; + } + else if (tn.element_type.type_special_kind == SemanticTree.type_special_kind.short_string) + { + base_function_call cmc = null; + if (SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info is common_namespace_function_node) + cmc = new common_namespace_function_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as common_namespace_function_node, null); + else + cmc = new compiled_static_method_call(SystemLibrary.SystemLibInitializer.ClipShortStringInSetFunction.sym_info as compiled_function_node, null); + cmc.parameters.AddElement(expr); + cmc.parameters.AddElement(new int_const_node((tn.element_type as short_string_type_node).Length, null)); + cmc.ret_type = tn; + return cmc; + } + } + return expr; + } + + public override void visit(SyntaxTree.new_expr _new_expr) + { + type_node tn = ret.visit(_new_expr.type); + if (tn is generic_instance_type_node gitn) // SSM 07/08/19 #2070 + gitn._is_abstract = gitn.original_generic.IsAbstract; + //if (tn == SystemLibrary.SystemLibrary.void_type) + // AddError(new VoidNotValid(get_location(_new_expr.type))); + if (tn.IsDelegate && !_new_expr.new_array) + AddError(get_location(_new_expr), "CONSTRUCTOR_CALL_FOR_DELEGATE_TYPES_IS_FORBIDDEN"); + check_for_type_allowed(tn,get_location(_new_expr.type)); + location loc = get_location(_new_expr); + expressions_list exprs = null; + var lambdas_are_in_parameters = false; + var syntax_nodes_parameters = _new_expr.params_list == null + ? new List() + : _new_expr.params_list.expressions; + + if (_new_expr.params_list != null) + { + exprs = new expressions_list(); + foreach (SyntaxTree.expression en in _new_expr.params_list.expressions) + { + if (en is SyntaxTree.function_lambda_definition) + { + lambdas_are_in_parameters = true; + ((SyntaxTree.function_lambda_definition)en).lambda_visit_mode = LambdaVisitMode.VisitForInitialMethodCallProcessing; + } + exprs.AddElement(convert_strong(en)); + } + } + else + exprs = new expressions_list(); + if (_new_expr.new_array) + { + check_using_static_class(tn, get_location(_new_expr.type)); + //if (exprs.Count == 1) + { + //new typename[size] + type_node atn = convertion_data_and_alghoritms.type_constructor.create_unsized_array(tn, context.converted_namespace, exprs.Count, loc); + //тип элементов + typeof_operator to = new typeof_operator(tn, loc); + List lst = new List(); + //размер + for (int i=0; i 1) + { + foreach (expression_node expr in lst) + if (!(expr is int_const_node)) + AddError(expr.location, "CONSTANT_EXPRESSION_EXPECTED"); + if (_new_expr.array_init_expr.elements == null) + AddError(get_location(_new_expr.array_init_expr), "ARRAY_CONST_EXPECTED"); + _new_expr.array_init_expr = get_possible_array_const(_new_expr.array_init_expr,atn) as SyntaxTree.array_const; + expression_node e = convert_strong(_new_expr.array_init_expr); + if (e is array_initializer) + { + array_initializer tmp = e as array_initializer; + for (int i=0; i>(lambdas_are_in_parameters, syntax_nodes_parameters))); + } + + public override void visit(SyntaxTree.where_type_specificator_list node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.where_definition node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.where_definition_list node) + { + throw new NotSupportedError(get_location(node)); + } + + private bool can_evaluate_size(type_node tn) + { + if (tn is compiled_type_node ctn1) + { + if (tn.type_special_kind == SemanticTree.type_special_kind.array_wrapper || tn.type_special_kind == SemanticTree.type_special_kind.set_type + || tn.type_special_kind == SemanticTree.type_special_kind.short_string || tn.type_special_kind == SemanticTree.type_special_kind.typed_file || tn.type_special_kind == SemanticTree.type_special_kind.text_file + || tn.type_special_kind == SemanticTree.type_special_kind.binary_file || tn.type_special_kind == SemanticTree.type_special_kind.array_kind) + return true; + if (tn.type_special_kind == SemanticTree.type_special_kind.diap_type || tn.type_special_kind == SemanticTree.type_special_kind.enum_kind) + return true; + if (tn.IsPointer) + return true; + if (tn.is_generic_parameter || tn.is_generic_type_definition || tn.is_generic_type_instance) + return false; + /*if (ctn1.compiled_type == typeof(System.IntPtr) || ctn1.compiled_type == typeof(System.UIntPtr)) + return false;*/ + } + if (tn is common_type_node) + { + common_type_node ctn = tn as common_type_node; + + if (ctn.type_special_kind == SemanticTree.type_special_kind.diap_type || ctn.type_special_kind == SemanticTree.type_special_kind.enum_kind) + return true; + if (tn.type_special_kind == SemanticTree.type_special_kind.array_wrapper || tn.type_special_kind == SemanticTree.type_special_kind.set_type || tn.type_special_kind == SemanticTree.type_special_kind.short_string + || tn.type_special_kind == SemanticTree.type_special_kind.typed_file || tn.type_special_kind == SemanticTree.type_special_kind.text_file + || tn.type_special_kind == SemanticTree.type_special_kind.binary_file || tn.type_special_kind == SemanticTree.type_special_kind.array_kind) + return true; + if (tn.IsPointer) + return true; + + if (tn.is_generic_parameter || tn.is_generic_type_definition || tn.is_generic_type_instance) + return false; + foreach (class_field cf in ctn.fields) + if (!cf.IsStatic) + if (!can_evaluate_size(cf.type)) return false; + + } + return true; + } + + private expression_node make_sizeof_operator(type_node tn, location loc) + { + return new sizeof_operator(tn,loc); + } + + public override void visit(SyntaxTree.sizeof_operator node) + { + if (node.type_def != null && node.type_def is SyntaxTree.named_type_reference) + { + SyntaxTree.named_type_reference ntr = node.type_def as SyntaxTree.named_type_reference; + type_node tn = find_type(ntr, get_location(ntr)); + switch (tn.type_special_kind) + { + case SemanticTree.type_special_kind.enum_kind: + if (tn is compiled_type_node ctn) + { + return_value(new int_const_node(System.Runtime.InteropServices.Marshal.SizeOf(ctn.compiled_type.GetEnumUnderlyingType()), get_location(ntr))); break; + } + else + { + return_value(new int_const_node(sizeof(int), get_location(ntr))); break; + } + default: + if (tn.is_generic_parameter || tn.is_generic_type_definition || tn.is_generic_type_instance) + { + AddError(get_location(ntr), "OPERATOR_SIZEOF_CAN_NOT_BE_USED_WITH_GENERIC_TYPE"); + } + if (!can_evaluate_size(tn)) + AddError(get_location(ntr), "CANNOT_EVALUATE_SIZE", tn.name); + return_value(make_sizeof_operator(tn, get_location(node))); + break; + } + } + else + throw new NotSupportedError(get_location(node)); + + } + + public override void visit(SyntaxTree.typeof_operator node) + { + return_value(new typeof_operator(find_type(node.type_name, get_location(node.type_name)), get_location(node))); + } + + public override void visit(SyntaxTree.compiler_directive node) + { + if (node.Name.text.ToLower() == compiler_string_consts.compiler_directive_faststrings) + { + SemanticRules.FastStrings = true; + return; + } + if (node.Name.text.ToLower() == compiler_string_consts.compiler_directive_nullbasedstrings) + { + SemanticRules.NullBasedStrings = node.Directive.text.ToLower() == compiler_string_consts.true_const_name; + return; + } + if (node.Name.text.ToLower() == compiler_string_consts.compiler_directive_nullbasedstrings_ON) + { + SemanticRules.NullBasedStrings = true; + return; + } + if (node.Name.text.ToLower() == compiler_string_consts.compiler_directive_nullbasedstrings_OFF) + { + SemanticRules.NullBasedStrings = false; + return; + } + if (node.Name.text.ToLower() == compiler_string_consts.compiler_directive_initstring_as_empty_ON) + { + SemanticRules.InitStringAsEmptyString = true; + return; + } + if (node.Name.text.ToLower() == compiler_string_consts.compiler_directive_initstring_as_empty_OFF) + { + SemanticRules.InitStringAsEmptyString = false; + return; + } + if (node.Name.text == "platform" && node.Directive.text.ToLower() == "native") + { + SemanticRules.GenerateNativeCode = true; + + + return; + } + } + + public override void visit(SyntaxTree.operator_name_ident node) + { + throw new NotSupportedError(get_location(node)); + } + + public override void visit(SyntaxTree.var_statement node) + { + visit(node.var_def); + ret.reset(); // SSM 19.01.17 не возвращать семантическое значение т.к. ничего не нужно добавлять в текущий список операторов!! + } + + public override void visit(SyntaxTree.expression_as_statement node) + { + return_value((statement_node)convert_strong(node.expr)); + } + + //ssyy + public void generate_inherit_constructors() + { + common_type_node _ctn = context.converted_type; + if (_ctn == null) + { + throw new CompilerInternalError("Can generate inherited constructors only in class."); + } + if (_ctn.IsStatic) + return; + if (_ctn.has_user_defined_constructor) + { + //Пользователь определил хотя бы один конструктор, никакие конструкторы не наследуем. + return; + } + //Получили список процедур предка, имеющих имя Create + List sil = _ctn.base_type.find_in_type(compiler_string_consts.default_constructor_name, _ctn.base_type.Scope); + delete_inherited_constructors(ref sil, _ctn.base_type); + if (sil != null) + { + foreach(SymbolInfo si in sil) + { + function_node fn = si.sym_info as function_node; + compiled_constructor_node pconstr = fn as compiled_constructor_node; + common_method_node mconstr = fn as common_method_node; + //Если это конструктор... + if (pconstr != null || + mconstr != null && mconstr.is_constructor) + { + //Генерируем унаследованный конструктор + location loc = null; + SemanticTree.polymorphic_state ps; + if (mconstr != null) + { + loc = mconstr.loc; + ps = mconstr.polymorphic_state; + } + else //значит (pconstr != null) + { + ps = pconstr.polymorphic_state; + } + if (pconstr != null) + context.set_field_access_level(pconstr.field_access_level); + else + context.set_field_access_level(mconstr.field_access_level); + common_method_node gen_constr = null; - if (fn.parameters.Count==0) - gen_constr = _ctn.methods.FirstOrDefault(m => - m.is_constructor && m.name==compiler_string_consts.default_constructor_name && m.parameters.Count==0 + if (fn.parameters.Count==0) + gen_constr = _ctn.methods.FirstOrDefault(m => + m.is_constructor && m.name==compiler_string_consts.default_constructor_name && m.parameters.Count==0 ); if (gen_constr!=null) { @@ -19385,1903 +19385,1903 @@ namespace PascalABCCompiler.TreeConverter gen_constr.is_overload = true; gen_constr.is_constructor = true; gen_constr.field_access_level = fn.field_access_level; - if (_ctn.IsPartial) - context.last_created_function.symbol_kind = symbol_kind.sk_overload_function; + if (_ctn.IsPartial) + context.last_created_function.symbol_kind = symbol_kind.sk_overload_function; gen_constr.return_value_type = _ctn; - } - - foreach (parameter par in fn.parameters) - { - //(ssyy) Интересно, зачем это. - concrete_parameter_type cpt = - (par.parameter_type == SemanticTree.parameter_type.var) ? - concrete_parameter_type.cpt_var : - concrete_parameter_type.cpt_none; - common_parameter c_p = new common_parameter(par.name, - par.parameter_type, gen_constr, cpt, null); - c_p.type = par.type; - c_p.set_param_is_params(par.is_params); - c_p.inital_value = par.inital_value; - gen_constr.parameters.AddElement(c_p); - c_p.default_value = par.default_value; - } - - base_function_call bfc; - - if (mconstr != null) - { - common_constructor_call c1 = new common_constructor_call(mconstr, null); - c1._new_obj_awaited = false; - bfc = c1; - } - else - { - compiled_constructor_call c2 = new compiled_constructor_call(pconstr, null); - c2._new_obj_awaited = false; - bfc = c2; - } - foreach (parameter p in gen_constr.parameters) - { - bfc.parameters.AddElement( - create_variable_reference(p, null)); - } - statements_list snlist = new statements_list(null); - snlist.statements.AddElement(bfc); - snlist.statements.AddElement(new empty_statement(null)); - gen_constr.function_code = snlist; - context.leave_block(); - if (fn.parameters.Count == 0 || fn.parameters[0].default_value != null) - { - _ctn.has_default_constructor = true; - } - } - } - } - } - //\ssyy - - //ssyy - public void generate_inherited_from_base_and_interface_function(common_type_node ctype, function_node func) - { - common_method_node gen_func = context.create_function(func.name, null) as common_method_node; - gen_func.polymorphic_state = SemanticTree.polymorphic_state.ps_common; - gen_func.newslot_awaited = true; - gen_func.is_final = true; - gen_func.is_overload = true; - gen_func.field_access_level = SemanticTree.field_access_level.fal_public; - gen_func.return_value_type = func.return_value_type; - //gen_func.return_variable = func.retu - - foreach (parameter par in func.parameters) - { - concrete_parameter_type cpt = - (par.parameter_type == SemanticTree.parameter_type.value) ? - concrete_parameter_type.cpt_const : - concrete_parameter_type.cpt_var; - common_parameter c_p = new common_parameter(par.name, - par.parameter_type, gen_func, cpt, null); - c_p.type = par.type; - c_p.set_param_is_params(par.is_params); - c_p.inital_value = par.inital_value; - gen_func.parameters.AddElement(c_p); - } - - local_variable lv = new local_variable(compiler_string_consts.self_word, gen_func.cont_type, gen_func, null); - gen_func.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv)); - gen_func.self_variable = lv; - - base_function_call bfc; - this_node tn = null; - - common_method_node commn = func as common_method_node; - if (commn != null) - { - tn = new this_node(commn.comperehensive_type as type_node, null); - bfc = new common_method_call(commn, tn, null); - } - else - { - compiled_function_node compn = func as compiled_function_node; - tn = new this_node(compn.comperehensive_type as type_node, null); - bfc = new compiled_function_call(compn, tn, null); - } - - foreach (parameter p in gen_func.parameters) - { - bfc.parameters.AddElement( - create_variable_reference(p, null)); - } - - //Это запретит чистку стека - bfc.last_result_function_call = true; - - statements_list snlist = new statements_list(null); - snlist.statements.AddElement(bfc); - snlist.statements.AddElement(new empty_statement(null)); - gen_func.function_code = snlist; - context.pop_top_function(); - //context.leave_block(); - } - //\ssyy - - private Dictionary WaitedRefTypes = new Dictionary(); - internal ref_type_node GetWaitedRefType(string name, location loc) - { - ref_type_node rtn = null; - if (WaitedRefTypes.TryGetValue(name, out rtn)) - return rtn; - rtn = new ref_type_node(null); - rtn.PointedTypeName = name; - rtn.loc = loc; - WaitedRefTypes.Add(name, rtn); - return rtn; - } - - internal List RefTypesForCheckPointersTypeForDotNetFramework = new List(); - void ProcessRefTypesForCheckPointersTypeForDotNetFramework() - { - foreach (ref_type_node rtn in RefTypesForCheckPointersTypeForDotNetFramework) - if (SemanticRules.StrongPointersTypeCheckForDotNet) - CheckPointersTypeForDotNetFramework(rtn.pointed_type, rtn.loc); - RefTypesForCheckPointersTypeForDotNetFramework.Clear(); - } - internal void CheckWaitedRefTypes(type_node tn) - { - ref_type_node rtn = null; - if (WaitedRefTypes.TryGetValue(tn.name, out rtn)) - { - if (SemanticRules.StrongPointersTypeCheckForDotNet) - RefTypesForCheckPointersTypeForDotNetFramework.Add(rtn); - rtn.SetPointedType(tn); - WaitedRefTypes.Remove(tn.name); - } - } - - internal void EnterTypeDeclarationsSection() - { - type_section_converting = true; - } - - internal void LeaveTypeDeclarationsSection() - { - type_section_converting = false; - if (context.types_predefined.Count > 0 && !context.namespace_converted) - { - AddError(context.types_predefined[0].loc, "NO_TYPE_{0}_DEFINITION", context.types_predefined[0].name); - } - foreach (string Name in WaitedRefTypes.Keys) - WaitedRefTypes[Name].SetPointedType(find_type(Name, WaitedRefTypes[Name].loc)); - foreach (ref_type_node rtn in WaitedRefTypes.Values) - CheckForCircularityInPointers(rtn, rtn.pointed_type,rtn.loc); - ProcessRefTypesForCheckPointersTypeForDotNetFramework(); - WaitedRefTypes.Clear(); - } - - internal void ProcessCheckPointersInRecord() - { - ProcessRefTypesForCheckPointersTypeForDotNetFramework(); - } - - public override void visit(SyntaxTree.c_scalar_type node) - { - Type t = null; - switch (node.scalar_name) - { - case SyntaxTree.c_scalar_type_name.tn_void: - t = typeof(void); - break; - case SyntaxTree.c_scalar_type_name.tn_char: - t = typeof(char); - break; - case SyntaxTree.c_scalar_type_name.tn_double: - t = typeof(double); - break; - case SyntaxTree.c_scalar_type_name.tn_float: - t = typeof(float); - break; - case SyntaxTree.c_scalar_type_name.tn_int: - t = (node.sign == SyntaxTree.c_scalar_sign.unsigned) ? - typeof(UInt32) : - typeof(Int32); - break; - case SyntaxTree.c_scalar_type_name.tn_long: - case SyntaxTree.c_scalar_type_name.tn_long_int: - t = (node.sign == SyntaxTree.c_scalar_sign.unsigned) ? - typeof(UInt64) : - typeof(Int64); - break; - case SyntaxTree.c_scalar_type_name.tn_short: - case SyntaxTree.c_scalar_type_name.tn_short_int: - t = typeof(Int16); - break; - } - ret.return_value(compiled_type_node.get_type_node(t)); - } - - public override void visit(SyntaxTree.c_module node) - { - string namespace_name = ""; - location loc = null; - // if (_program_module.program_name != null) - // { - // namespace_name = _program_module.program_name.prog_name.name; - // loc = get_location(_program_module.program_name.prog_name); - // if (namespace_name.ToLower() != System.IO.Path.GetFileNameWithoutExtension(_program_module.file_name).ToLower()) - // throw new ProgramNameMustBeEqualProgramFileName(loc); - // } - - - _compiled_unit = new common_unit_node(); - - _compiled_unit.compiler_directives = ConvertDirectives(node); - //PrepareDirectives(_compiled_unit.compiler_directives); - - //using_list.AddRange(interface_using_list); - //weak_node_test_and_visit(_program_module.using_namespaces); - //weak_node_test_and_visit(node.used_units); - - //compiled_main_unit=new unit_node(); - //SymbolTable.Scope[] used_units=new SymbolTable.Scope[used_assemblyes.Count+1]; - - SymbolTable.Scope[] used_units = build_referenced_units(referenced_units,true); - - _compiled_unit.scope = convertion_data_and_alghoritms.symbol_table.CreateUnitInterfaceScope(used_units, namespace_name); - - common_namespace_node cnsn = context.create_namespace(namespace_name, _compiled_unit, _compiled_unit.scope, loc); - cnsn.is_main = true; - //compiled_program=new program_node(); - //compiled_program.units.Add(compiled_main_unit); - - reset_for_interface(); - - UpdateUnitDefinitionItemForUnit(_compiled_unit); - - //_program_module.program_block.visit(this); - //hard_node_test_and_visit(_program_module.program_block); - //context.check_labels(context.converted_namespace.labels); - - //TODO: Доделать. - //common_namespace_function_node main_function = new common_namespace_function_node(compiler_string_consts.temp_main_function_name, - // null, null, cnsn, null); - //main_function.function_code = context.code; - //cnsn.functions.AddElement(main_function); - - weak_node_test_and_visit(node.defs); - - bool main_not_found = true; - foreach (function_node fn in cnsn.functions) - { - if (fn.name == compiler_string_consts.c_main_function_name) - { - _compiled_unit.main_function = fn as common_namespace_function_node; - //context.apply_special_local_vars(_compiled_unit.main_function); - main_not_found = false; - break; - } - } - if (main_not_found) - { - AddError(get_location(node), "NO_MAIN_FUNCTION"); - } - - context.leave_block(); - - //_compiled_unit.main_function = main_function; - - } - - public override void visit(SyntaxTree.declarations_as_statement node) - { - //throw new NotSupportedError(get_location(node)); - node.defs.visit(this); - return_value(new empty_statement(null)); - } - public override void visit(SyntaxTree.array_size node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.enumerator node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.enumerator_list node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.c_for_cycle node) - { - //throw new NotSupportedError(get_location(node)); - location loc1 = get_location(node.expr1); - statements_list head_stmts = new statements_list(loc1); - convertion_data_and_alghoritms.statement_list_stack_push(head_stmts); - //statement_node sn_init = convert_weak((SyntaxTree.statement)node.expr1); // SSM 12/06/15 - всё равно c-узлы никому не нужны - statement_node sn_init = convert_weak(node.expr1); // SSM 12/06/15 - expression_node sn_cond = convert_weak(node.expr2); - //statement_node sn_next = convert_weak((SyntaxTree.statement)node.expr3); // SSM 12/06/15 - statement_node sn_next = convert_weak(node.expr3); // SSM 12/06/15 - - CheckToEmbeddedStatementCannotBeADeclaration(node.stmt); - - for_node fn = new for_node(sn_init, sn_cond, null, sn_next, null, get_location(node)); - context.cycle_stack.push(fn); - - statements_list slst = new statements_list(get_location(node.stmt)); - convertion_data_and_alghoritms.statement_list_stack_push(slst); - - context.enter_code_block_with_bind(); - fn.body = convert_strong(node.stmt); - context.leave_code_block(); - - slst = convertion_data_and_alghoritms.statement_list_stack.pop(); - if (slst.statements.Count > 0 || slst.local_variables.Count > 0) - { - slst.statements.AddElement(fn.body); - fn.body = slst; - } - - context.cycle_stack.pop(); - - head_stmts = convertion_data_and_alghoritms.statement_list_stack.pop(); - head_stmts.statements.AddElement(fn); - return_value(head_stmts); - - /*slst = convertion_data_and_alghoritms.statement_list_stack.pop(); - if (slst.statements.Count > 0 || slst.local_variables.Count > 0) - { - slst.statements.AddElement(fn.body); - fn.body = slst; - } - - context.cycle_stack.pop();*/ - //ret.return_value(slst); - } - public override void visit(SyntaxTree.switch_stmt node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.type_definition_attr node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.type_definition_attr_list node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.lock_stmt node) - { - expression_node lock_object = convert_strong(node.lock_object); - //Нужно ли это??? - if (lock_object.type.semantic_node_type == semantic_node_type.delegated_method) - try_convert_typed_expression_to_function_call(ref lock_object); - if (lock_object.type == null || lock_object.type.is_value_type) - AddError(get_location(node.lock_object), "EXPRESSION_IN_LOCK_STATEMENT_RETURNED_NOT_A_REFERENCE_TYPE", lock_object.type); - CheckToEmbeddedStatementCannotBeADeclaration(node.stmt); - statement_node stmt = convert_strong(node.stmt); - return_value(new lock_statement(lock_object, stmt, get_location(node))); - } - public override void visit(SyntaxTree.compiler_directive_list node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.compiler_directive_if node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.documentation_comment_list node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.documentation_comment_section node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.documentation_comment_tag node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.documentation_comment_tag_param node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.token_taginfo node) - { - throw new NotSupportedError(get_location(node)); - } - public override void visit(SyntaxTree.declaration_specificator node) - { - throw new NotSupportedError(get_location(node)); - } - - public override void visit(SyntaxTree.ident_with_templateparams _ident_with_templateparams) - { - SyntaxTree.expression ex = _ident_with_templateparams.name; - SyntaxTree.ident id_ex = _ident_with_templateparams.name as SyntaxTree.ident; - dot_node dn = _ident_with_templateparams.name as dot_node; - int par_count = _ident_with_templateparams.template_params.params_list.Count; - if (id_ex != null) - { - SymbolInfo type_si = context.find_first(id_ex.name + compiler_string_consts.generic_params_infix + par_count.ToString()); - if (type_si != null) - { - return_value(get_generic_instance(type_si, _ident_with_templateparams.template_params.params_list)); - return; - } - type_si = context.find_first(id_ex.name); - if (type_si != null && type_si.sym_info.general_node_type == general_node_type.template_type) - { - template_class tc = type_si.sym_info as template_class; - List tpars = visit_type_list(_ident_with_templateparams.template_params.params_list); - return_value(instance_any(tc, tpars, get_location(_ident_with_templateparams))); - return; - } - } - else if (dn != null && dn.right is ident) - { - semantic_node sn = convert_semantic_strong(dn.left); - id_ex = dn.right as SyntaxTree.ident; - type_node tn = null; - namespace_node nn = null; - unit_node un = null; - switch (sn.general_node_type) - { - case general_node_type.expression: tn = (sn as expression_node).type; break; - case general_node_type.type_node: tn = sn as type_node; break; - case general_node_type.namespace_node: nn = sn as namespace_node; break; - case general_node_type.unit_node: un = sn as unit_node; break; - default: - AddError(get_location(dn.left), "EXPECTED_ANOTHER_KIND_OF_OBJECT"); break; - } - List type_sil = null; - if (tn != null) - { - type_sil = tn.find_in_type(id_ex.name + compiler_string_consts.generic_params_infix + par_count.ToString()); - } - else if (nn != null) - { - type_sil = nn.find(id_ex.name + compiler_string_consts.generic_params_infix + par_count.ToString()); - } - else if (un != null) - { - type_sil = un.find_only_in_namespace(id_ex.name + compiler_string_consts.generic_params_infix + par_count.ToString()); - } - if (type_sil != null) - { - return_value(get_generic_instance(type_sil?.FirstOrDefault(), _ident_with_templateparams.template_params.params_list)); - return; - } - if (tn != null) - { - type_sil = tn.find_in_type(id_ex.name); - } - else if (nn != null) - { - type_sil = nn.find(id_ex.name); - } - else if (un != null) - { - type_sil = un.find_only_in_namespace(id_ex.name); - } - if (type_sil != null && type_sil.FirstOrDefault().sym_info.general_node_type == general_node_type.template_type) - { - template_class tc = type_sil.FirstOrDefault().sym_info as template_class; - List tpars = visit_type_list(_ident_with_templateparams.template_params.params_list); - return_value(instance_any(tc, tpars, get_location(_ident_with_templateparams))); - return; - } - dot_node dn2 = new dot_node(dn.left, new ident_with_templateparams(dn.right, _ident_with_templateparams.template_params, dn.right.source_context), dn.source_context); - ex = dn2; - } - - expression_node adr = ret.visit(ex); - typed_expression te = adr as typed_expression; - if (te != null) - { - delegated_methods dm = te.type as delegated_methods; - if (dm != null) - { - List ptypes = visit_type_list(_ident_with_templateparams.template_params.params_list); - base_function_call_list bfcl = new base_function_call_list(); - common_method_node cnode; - compiled_function_node comp_node; - function_node fnode; - int generic_count = 0; - foreach (base_function_call bfc in dm.proper_methods) - { - if (bfc.simple_function_node.is_generic_function) - { - generic_count++; - } - } - bool one_function = false; - switch (generic_count) - { - case 0: - AddError(get_location(_ident_with_templateparams), "TRIANGLE_BRACKETS_NOT_ALLOWED_WITH_COMMON_FUNCTIONS"); break; - case 1: - one_function = true; - break; - default: - one_function = false; - break; - } - foreach (base_function_call bfc in dm.proper_methods) - { - if (!bfc.simple_function_node.is_generic_function) - { - continue; - } - switch (bfc.semantic_node_type) - { - case semantic_node_type.common_namespace_function_call: - common_namespace_function_node cnfn = bfc.simple_function_node.get_instance(ptypes, one_function, get_location(_ident_with_templateparams)) as common_namespace_function_node; - if (cnfn != null) - { - bfcl.AddElement(new common_namespace_function_call(cnfn, bfc.location)); - } - break; - case semantic_node_type.common_method_call: - cnode = bfc.simple_function_node.get_instance(ptypes, one_function, get_location(_ident_with_templateparams)) as common_method_node; - if (cnode != null) - { - bfcl.AddElement(new common_method_call(cnode, (bfc as common_method_call).obj, bfc.location)); - } - break; - case semantic_node_type.compiled_function_call: - fnode = bfc.simple_function_node.get_instance(ptypes, one_function, get_location(_ident_with_templateparams)); - cnode = fnode as common_method_node; - if (cnode != null) - { - bfcl.AddElement(new common_method_call(cnode, (bfc as compiled_function_call).obj, bfc.location)); - } - else - { - comp_node = fnode as compiled_function_node; - if (comp_node != null) - { - bfcl.AddElement(new compiled_function_call(comp_node, (bfc as compiled_function_call).obj, bfc.location)); - } - } - break; - case semantic_node_type.common_static_method_call: - case semantic_node_type.compiled_static_method_call: - fnode = bfc.simple_function_node.get_instance(ptypes, one_function, get_location(_ident_with_templateparams)); - cnode = fnode as common_method_node; - if (cnode != null) - { - bfcl.AddElement(new common_static_method_call(cnode, bfc.location)); - } - else - { - comp_node = fnode as compiled_function_node; - if (comp_node != null) - { - bfcl.AddElement(new compiled_static_method_call(comp_node, bfc.location)); - } - } - break; - } - } - if (bfcl.Count == 0) - { - AddError(get_location(_ident_with_templateparams.template_params), "NO_FUNCTIONS_{0}_CAN_BE_USED_WITH_THIS_SPECIFICATION", dm.proper_methods[0].function.name); - } - delegated_methods dm1 = new delegated_methods(); - dm1.proper_methods.AddRange(bfcl); - typed_expression te1 = new typed_expression(dm1, te.location); - return_value(te1); - return; - } - } - if (!(adr is compiled_static_method_call) && !(adr is common_static_method_call) && !(adr is common_namespace_function_call)) - AddError(get_location(_ident_with_templateparams.name), "TRIANGLE_BRACKETS_NOT_AWAITED"); - } - - public override void visit(SyntaxTree.template_type_name node) - { - throw new NotSupportedError(get_location(node)); - } - - public override void visit(SyntaxTree.default_operator _default_operator) - { - type_node tn = ret.visit(_default_operator.type_name); - if (tn == null) - { - AddError(get_location(_default_operator), "TYPE_REFERENCE_EXPECTED"); - } - if (tn == SystemLibrary.SystemLibrary.void_type) - { - AddError(get_location(_default_operator.type_name), "INAVLID_TYPE"); - } - return_value(new default_operator_node(tn, get_location(_default_operator))); - //throw new NotSupportedError(get_location(_default_operator)); - } - - public override void visit(SyntaxTree.bracket_expr _bracket_expr) - { - _bracket_expr.expr.visit(this); - } - - public override void visit(SyntaxTree.attribute _attribute) - { - - } - - public override void visit(SyntaxTree.attribute_list _attribute_list) - { - - } - - public override void visit(SyntaxTree.simple_attribute_list _simple_attribute_list) - { - - } - - public override void visit(closure_substituting_node _closure_substituting_node) - { - visit(_closure_substituting_node.substitution); - } - - public void MaybeConvertFunctionLambdaDefinitionToProcedureLambdaDefinition(function_lambda_definition _function_lambda_definition) - { - // SSM 23/07/16 - вроде сделал лучше в LambdaHelper.InferTypesFromVarStmt, но пока везде удалять вызов этой функции не решаюсь - лень тестировать - // SSM 18/04/16 попытка разрешить x->Print(x) - var stl = _function_lambda_definition.proc_body as SyntaxTree.statement_list; - if (_function_lambda_definition.return_type is lambda_inferred_type && stl != null && stl.list.Count == 1 && _function_lambda_definition.usedkeyword == 0) - { - 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; - // Надо посмотреть, как это делается для преобразования типов T(x). А пока так - expression_node qq = null; - delegated_methods dm = null; - common_type_node delegate_type = null; - int err_cnt = ErrorsList.Count; - try - { - // Видимо, дело только в лямбде. Попробовать всё обойти и найти захваченные параметры - // Если они есть, то ничего не делать и выйти - - var vis = HasCapturedLambdaParameterInInternalLambdaBody.New(_function_lambda_definition); - vis.ProcessNode(ff.dereferencing_value); - if (vis.HasCapturedParameter) // SSM 28/01/2021 считать это функцией. Будет слабый вывод в редком числе случаев - return; - - qq = convert_strong(ff.dereferencing_value); - if (qq is exit_procedure && stl.list.Count == 1 || qq is local_block_variable_reference && qq.type is compiled_type_node && (qq.type as compiled_type_node).compiled_type == typeof(Action)) - { - // SSM #2172 27/06/20 - тело - это вызов exit - stl.list[0] = new procedure_call(ff, ff.source_context); - _function_lambda_definition.return_type = null; - return; - } - dm = qq.type as delegated_methods; - if (dm == null && qq.type != null && qq.type.IsDelegate) - delegate_type = qq.type as common_type_node; - - } - catch (Exception e) - { - if (ErrorsList.Count != err_cnt)//delete fake errors - ErrorsList.RemoveRange(err_cnt, ErrorsList.Count - err_cnt); - // Погасить все исключения. Значит, не вывелось, и в правой части лямбды - не вызов процедуры, а скорее всего приведение типа T(x) - // К сожалению, сюда попадает случай a->a.Print() где a до более позднего этапа не определяется - // Плохо, но лучше пока не получается - } - if (dm != null && dm.proper_methods != null && dm.proper_methods.Count > 0) - { - if (dm.proper_methods[0].ret_type == null && stl.expr_lambda_body) - { - // Очищаем от Result := - stl.list[0] = new procedure_call(ff, ff.source_context); // заменить result := Print(x) на Print(x) - _function_lambda_definition.return_type = null; - } - } - else if (delegate_type != null) - { - function_node fn = delegate_type.find_in_type("Invoke")[0].sym_info as function_node; - if (fn.return_value_type == null && stl.expr_lambda_body) - { - stl.list[0] = new procedure_call(ff, ff.source_context); - _function_lambda_definition.return_type = null; - } - } - } - } - else - if (!stl.expr_lambda_body) // SSM 26.11.18 - // значит, первый и единственный оператор - не присваивание и это лямбда - процедура! - { - var rns = new LambdaHelper.ResultNodesSearcher(_function_lambda_definition.proc_body); - if (rns.exprList.Count == 0) // Значит, это процедура, т.к. в блоке begin-end нет ни одного result := ... - { - _function_lambda_definition.return_type = null; - } - else _function_lambda_definition.usedkeyword = 1; // значит, это наверняка функция - } - } - else if (_function_lambda_definition.return_type is lambda_inferred_type && stl != null && stl.list.Count > 1 && _function_lambda_definition.usedkeyword == 0) - { - var rns = new LambdaHelper.ResultNodesSearcher(_function_lambda_definition.proc_body); - if (rns.exprList.Count == 0) // Значит, это процедура, т.к. в блоке begin-end нет ни одного result := ... - { - _function_lambda_definition.return_type = null; - } - else _function_lambda_definition.usedkeyword = 1; // значит, это наверняка функция - } - } - - public expression ProcedureForLambdaAndVisit(function_lambda_definition lambdaDefinition, ident_list tempParsList, where_definition_list whereSection) - { - var procDecl = LambdaHelper.ConvertLambdaNodeToProcDefNode(lambdaDefinition); - - if (tempParsList != null) - { - procDecl.proc_header.template_args = tempParsList; - } - - if (whereSection != null && whereSection.defs != null && whereSection.defs.Count != 0) - { - procDecl.proc_header.where_defs = whereSection; - } - - if (!context.func_stack.Empty && context.func_stack.top().polymorphic_state == SemanticTree.polymorphic_state.ps_static - || context.converted_type != null && context.converted_type.IsStatic) - { - procDecl.proc_header.class_keyword = true; - if (procDecl.proc_header.proc_attributes == null) - procDecl.proc_header.proc_attributes = new SyntaxTree.procedure_attributes_list(); - procDecl.proc_header.proc_attributes.proc_attributes.Add(new SyntaxTree.procedure_attribute(PascalABCCompiler.SyntaxTree.proc_attribute.attr_static)); - } - - try - { - visit(procDecl); - } - catch (Exception e) - { - context.remove_lambda_function(procDecl.proc_header.name.meth_name.name, true); - throw; - } - - context.remove_lambda_function(procDecl.proc_header.name.meth_name.name, false); - - return tempParsList == null ? - (expression)procDecl.proc_header.name.meth_name : - (expression)new ident_with_templateparams(procDecl.proc_header.name.meth_name, new template_param_list(tempParsList.idents.Select(l => SyntaxTreeBuilder.BuildSimpleType(l.name)).ToList())); - - } - - int ccc = 0; - public override void visit(SyntaxTree.function_lambda_definition _function_lambda_definition) - { -#if DEBUG - /*if (lambdaProcessingState == LambdaProcessingState.ClosuresProcessingPhase) - { - var s = new string (' ',ccc)+"begin " + _function_lambda_definition.lambda_name + " " + _function_lambda_definition.parameters.expressions[0] + "\n"; - ccc += 2; - System.IO.File.AppendAllText("d:\\bb3.txt", s); - }*/ -#endif - //stl.list[0] = new procedure_call(ff, ff.source_context); - Это надо для превращения функции в процедуру - //_function_lambda_definition.return_type = null; - - - _function_lambda_definition.RealSemTypeOfResExpr = null; // После первого присваивания Result она будет содержать тип type_node в правой части Result - _function_lambda_definition.RealSemTypeOfResult = null; - try - { - stflambda.Push(_function_lambda_definition); - if (_function_lambda_definition.substituting_node != null) - { - if (_function_lambda_definition.substituting_node is dot_node) - { - visit((dot_node)_function_lambda_definition.substituting_node); - } - else if (_function_lambda_definition.substituting_node is ident) - { - visit((ident)_function_lambda_definition.substituting_node); - } - else if (_function_lambda_definition.substituting_node is ident_with_templateparams) - { - visit((ident_with_templateparams)_function_lambda_definition.substituting_node); - } - return; - } - // Внутри makeProcedureForLambdaAndVisit делается procdecl или funcdecl и обходится. - // Поэтому формальный параметр обходится точно!! - //Func makeProcedureForLambdaAndVisit = ProcedureForLambdaAndVisit; - - switch (lambdaProcessingState) - { - case LambdaProcessingState.TypeInferencePhase: - { - MaybeConvertFunctionLambdaDefinitionToProcedureLambdaDefinition(_function_lambda_definition); - if (_function_lambda_definition.lambda_visit_mode == - LambdaVisitMode.VisitForAdvancedMethodCallProcessing) - { - ProcedureForLambdaAndVisit(_function_lambda_definition, null, null); - if (!LambdaHelper.IsAuxiliaryLambdaName(_function_lambda_definition.lambda_name)) - { - LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, _function_lambda_definition); - } - } - - ret.return_value((semantic_node)LambdaHelper.GetTempFunctionNodeForTypeInference(_function_lambda_definition, this)); - - break; - } - case LambdaProcessingState.FinishPhase: - { - if (context.top_function != null && context.top_function.generic_params != null) - { - var pars = context.top_function.generic_params.Select(par => new ident(par.name)).ToList(); - - var whereSection = - CapturedVariablesSubstitutor.GetWhereSection( - generic_parameter_eliminations.make_eliminations_common( - context.top_function.generic_params), pars); - - if (_function_lambda_definition.formal_parameters != null && _function_lambda_definition.formal_parameters.params_list.Count > 0) - { - for (var j = 0; j < _function_lambda_definition.formal_parameters.params_list.Count; j++) - { - if (_function_lambda_definition.formal_parameters.params_list[j].vars_type is lambda_inferred_type) - { - if ((_function_lambda_definition.formal_parameters.params_list[j].vars_type as lambda_inferred_type).real_type is type_node) - { - _function_lambda_definition.formal_parameters.params_list[j].vars_type = - LambdaHelper.ConvertSemanticTypeToSyntaxType((type_node)(_function_lambda_definition.formal_parameters.params_list[j].vars_type as lambda_inferred_type).real_type); - } - } - } - } - - if (_function_lambda_definition.return_type is lambda_inferred_type) - { - if ((_function_lambda_definition.return_type as lambda_inferred_type).real_type is type_node) - { - _function_lambda_definition.return_type = LambdaHelper.ConvertSemanticTypeToSyntaxType((type_node)(_function_lambda_definition.return_type as lambda_inferred_type).real_type); - } - } - - var methodNameToVisit = (ident_with_templateparams)ProcedureForLambdaAndVisit(_function_lambda_definition, new ident_list(pars), whereSection); - _function_lambda_definition.substituting_node = methodNameToVisit; - visit(methodNameToVisit); - } - else - { - var methodNameToVisit = (ident)ProcedureForLambdaAndVisit(_function_lambda_definition, null, null); - _function_lambda_definition.substituting_node = methodNameToVisit; - visit(methodNameToVisit); - } - break; - } - case LambdaProcessingState.ClosuresProcessingPhase: - { -#if DEBUG - //var s = "begin "+_function_lambda_definition.lambda_name + " "+ _function_lambda_definition.parameters.expressions[0] + "\n"; - //System.IO.File.AppendAllText("d:\\bb17.txt", s); -#endif - ProcedureForLambdaAndVisit(_function_lambda_definition, null, null); - LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, _function_lambda_definition); - ret.return_value((semantic_node)LambdaHelper.GetTempFunctionNodeForTypeInference(_function_lambda_definition, this)); - break; - } - case LambdaProcessingState.ClosuresProcessingVisitGeneratedClassesPhase: - { - ProcedureForLambdaAndVisit(_function_lambda_definition, null, null); - break; - } - case LambdaProcessingState.None: - { - if (context.converting_block() == block_type.namespace_block) - { - var methodNameToVisit = (ident)ProcedureForLambdaAndVisit(_function_lambda_definition, null, null); - _function_lambda_definition.substituting_node = methodNameToVisit; - visit(methodNameToVisit); - } - break; - } - } - } - finally - { - stflambda.Pop(); -#if DEBUG - /*if (lambdaProcessingState == LambdaProcessingState.ClosuresProcessingPhase) - { - ccc -= 2; - var s = new string(' ', ccc) + "end " + _function_lambda_definition.lambda_name + " " + _function_lambda_definition.parameters.expressions[0] + "\n"; - System.IO.File.AppendAllText("d:\\bb3.txt", s); - }*/ -#endif - } - } - - public override void visit(SyntaxTree.function_lambda_call _function_lambda_call) - { - SyntaxTree.op_type_node _op_type_node = new SyntaxTree.op_type_node(SyntaxTree.Operators.Assignment); - for (int i = 0; i < _function_lambda_call.parameters.expressions.Count; i++) - { - SyntaxTree.assign _assign = new SyntaxTree.assign(_function_lambda_call.f_lambda_def.parameters.expressions[i] as SyntaxTree.addressed_value, _function_lambda_call.parameters.expressions[i] as SyntaxTree.expression, _op_type_node.type); - ((SyntaxTree.statement_list)_function_lambda_call.f_lambda_def.proc_body).subnodes.Insert(0, _assign); - _assign.source_context = _function_lambda_call.source_context; - } - SyntaxTree.expression_list el = new SyntaxTree.expression_list(); - for (int i = 0; i < _function_lambda_call.f_lambda_def.formal_parameters.params_list.Count; i++) - if (i < _function_lambda_call.parameters.expressions.Count) - el.expressions.Add(_function_lambda_call.parameters.expressions[i]); - else - { - el.expressions.Add(new SyntaxTree.ident(_function_lambda_call.f_lambda_def.formal_parameters.params_list[i].idents.idents[0].name, _function_lambda_call.source_context)); - } - SyntaxTree.method_call _method_call = new SyntaxTree.method_call(el); - _method_call.source_context = _function_lambda_call.source_context; - if (_method_call is SyntaxTree.dereference) - { - ((SyntaxTree.dereference)_method_call).dereferencing_value = (SyntaxTree.addressed_value)(new SyntaxTree.ident(_function_lambda_call.f_lambda_def.lambda_name, _function_lambda_call.source_context)); - } - _method_call.visit(this); - } - - public void lambda_header_visit(SymbolInfo si, SyntaxTree.function_header _function_header, type_node tn1) - { - type_node tn = null; - if (_function_header.return_type == null) - { - if (context.top_function.IsOperator) - AddError(get_location(_function_header), "FUNCTION_NEED_RETURN_TYPE"); - } - if (_function_header.return_type != null) - { - check_parameter_on_complex_type(_function_header.return_type); - if (tn1 != null) - tn = tn1; - else - tn = convert_strong(_function_header.return_type); - //if (tn == SystemLibrary.SystemLibrary.void_type) - // AddError(new VoidNotValid(get_location(_function_header.return_type))); - check_for_type_allowed(tn, get_location(_function_header.return_type)); - } - //(ssyy) moved up, так как при проверке аттрибута override надо знать тип возвращаемого значения - context.top_function.return_value_type = tn; - assign_doc_info(context.top_function, _function_header); - if (_function_header.attributes != null) - { - make_attributes_for_declaration(_function_header, context.top_function); - } - if (context.converted_type != null && has_dll_import_attribute(context.top_function)) - AddError(get_dll_import_attribute(context.top_function).location, "DLLIMPORT_ATTRIBUTE_CANNOT_BE_APPLIED_TO_METHOD"); - if (_function_header.name.class_name != null) - with_class_name = true; - if (_function_header.class_keyword && !has_static_attr(_function_header.proc_attributes.proc_attributes)) - { - SyntaxTree.procedure_attribute pa = new SyntaxTree.procedure_attribute(PascalABCCompiler.SyntaxTree.proc_attribute.attr_static); - pa.source_context = _function_header.source_context; - _function_header.proc_attributes.proc_attributes.Add(pa); - } - weak_node_test_and_visit(_function_header.proc_attributes); - if (context.top_function.IsOperator) - { - common_method_node cmmn = context.top_function as common_method_node; - //if (cmmn == null) - //{ - // throw new OverloadOperatorMustBeStaticFunction(get_location(_function_header), context.top_function); - //} - if (cmmn != null && cmmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) - { - AddError(get_location(_function_header), "OVERLOADED_OPERATOR_MUST_BE_STATIC_FUNCTION"); - } - if (cmmn != null && (cmmn.name == compiler_string_consts.implicit_operator_name || cmmn.name == compiler_string_consts.explicit_operator_name)) - if (!convertion_data_and_alghoritms.eq_type_nodes(tn, cmmn.comperehensive_type as type_node) && !convertion_data_and_alghoritms.eq_type_nodes(cmmn.comperehensive_type as type_node, cmmn.parameters[0].type)) - { - AddError(get_location(_function_header.return_type), "RETURN_VALUE_SHOULD_HAVE_TYPE_{0}", (cmmn.comperehensive_type as type_node).PrintableName); - } - else if (convertion_data_and_alghoritms.eq_type_nodes(tn, cmmn.parameters[0].type)) - { - AddError(get_location(_function_header), "CIRCURAL_TYPE_CONVERSION_DEFINITION"); - } - } - with_class_name = false; - if (context.top_function != null && context.top_function is common_namespace_function_node && (context.top_function as common_namespace_function_node).ConnectedToType != null && !context.top_function.IsOperator) - { - concrete_parameter_type cpt = concrete_parameter_type.cpt_none; - SemanticTree.parameter_type pt = PascalABCCompiler.SemanticTree.parameter_type.value; - if ((context.top_function as common_namespace_function_node).ConnectedToType.is_value_type) - { - cpt = concrete_parameter_type.cpt_var; - pt = PascalABCCompiler.SemanticTree.parameter_type.var; - } - common_parameter cp = new common_parameter(compiler_string_consts.self_word, (context.top_function as common_namespace_function_node).ConnectedToType, pt, - context.top_function, cpt, null, null); - context.top_function.parameters.AddElementFirst(cp); - context.top_function.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(cp)); - } - CheckOverrideOrReintroduceExpectedWarning(get_location(_function_header)); - - bool unique = context.close_function_params(body_exists); - if (context.top_function.return_value_type == null) - AddError(get_location(_function_header), "FUNCTION_NEED_RETURN_TYPE"); - if (_function_header.where_defs != null) - { - if (unique) - { - visit_where_list(_function_header.where_defs); - } - else - { - AddError(get_location(_function_header.where_defs), "WHERE_SECTION_MUST_BE_ONLY_IN_FIRST_DECLARATION"); - } - } - convertion_data_and_alghoritms.create_function_return_variable(context.top_function, si); - - /*if (_function_header.name != null && context.converted_compiled_type != null && context.top_function is common_namespace_function_node) - { - if (context.FindMethodToOverride(context.top_function as common_namespace_function_node) != null) - AddError(new CanNotDeclareExtensionMethodAsOverrided(get_location(_function_header))); - }*/ - //TODO: Разобрать подробнее. - if (!body_exists) - { - if ((context.top_function.semantic_node_type == semantic_node_type.common_method_node) - || ((context.func_stack_size_is_one()) && (_is_interface_part))) - { - context.leave_block(); - } - } - body_exists = false; - } - - - public override void visit(SyntaxTree.lambda_inferred_type lit) //lroman// - { - return_value(lit.real_type as type_node); - } - - public override void visit(SyntaxTree.semantic_check sem) - { - if (sem == null) - return; - switch (sem.CheckName) - { - case "ExprIsInteger": - var ex = (SyntaxTree.expression)sem.param[0]; - expression_node en = convert_strong(ex); - en.location = get_location(ex); - if (en.type != SystemLibrary.SystemLibrary.integer_type) - AddError(get_location(ex), "STRING_CONSTANT_OR_IDENTIFIER_EXPECTED"); - break; - case " ": - break; - case " ": - break; - } - } - - public override void visit(SyntaxTree.same_type_node st) // SSM 22/06/13 - { - expression_node en = convert_strong(st.ex); - if (en == null) - AddError(get_location(st.ex),"CANNOT_EVALUATE_FUNCTION_TYPE"); - return_value(en.type); - } - - public type_node try_calc_expr_type(SyntaxTree.expression ex) // SSM 10.07.13 - { - try - { - expression_node en = convert_strong(ex); - return en.type; - } - catch (Exception e) - { - return new undefined_type("#UndefType", null); - } - } - - public override void visit(SyntaxTree.semantic_type_node stn) - { - return_value(stn.type as type_node); - } - - // SSM 10.01.16 впервые для реализации Tuple - t[0] - public override void visit(SyntaxTree.semantic_addr_value sav) - { - return_value(sav.expr as expression_node); - } - - public bool SameTypeAutoClasses(List names, List types, common_type_node t) - { - if (t.properties.Count() != names.Count()) - return false; - - var tnames = t.properties.Select(tt => tt.name); - - return types.SequenceEqual(t.fields.Select(tt => tt.type)) && names.SequenceEqual(tnames, StringComparer.OrdinalIgnoreCase); - //return true; - } - - public override void visit(SyntaxTree.unnamed_type_object unn) // SSM 27.06.13 - { - var l = unn.ne_list; - var names = l.name_expr.Select(x=>x.name).ToList(); - var strnames = names.Select(id=>id.name).ToList(); // преобразование idents в строки - - /*var tt1 = l.name_expr[0].expr; - var tse = convert_strong(tt1);*/ - - var semantic_exprs = l.name_expr.Select(x => convert_strong(x.expr)).ToList(); - for (var i = 0; i < semantic_exprs.Count; i++) - { - var ex = semantic_exprs[i]; - try_convert_typed_expression_to_function_call(ref ex); - semantic_exprs[i] = ex; - } - - var semantic_types = semantic_exprs.Select(x => x.type).ToList(); - var types = semantic_types.Select(x => SyntaxTreeBuilder.BuildSemanticType(x)).ToList(); - - contextChanger.SaveContextAndUpToGlobalLevel(); - - var tt = context._cmn.types.Where(t => t.name.StartsWith("AnonymousType#")); // найти все анонимные типы, полученные в текущей компиляции - - var typ = tt.FirstOrDefault(t => SameTypeAutoClasses(strnames, semantic_types, t)); // найти структурно совпадающий уже существующий анонимный тип - - // Генерация глобальных описаний - перенесена с синтаксического уровня - if (typ != null) - unn.set_name(typ.name); // если нашли, то просто меняем имя на имя этого класса - else - { - var td = SyntaxTreeBuilder.BuildAutoClass(unn.name(), names, types, unn.is_class); - visit(td); - } - - contextChanger.RestoreCurrentContext(); - - // Сахарный узел. Переадресация дальнейшей генерации узлу new_ex - visit(unn.new_ex); - } - - public override void visit(SyntaxTree.short_func_definition def) // SSM 20.07.13 - { - // Сахарный узел. Переадресация дальнейшей генерации узлу procedure_definition - visit(def.procdef); - } - - public override void visit(matching_expression _matching_expression) - { - throw new NotSupportedError(get_location(_matching_expression)); - } - - public override void visit(SyntaxTree.sequence_type _sequence_type) // сахарный узел - { - var pt = _sequence_type.elements_type.DescendantNodes(TraversalType.PostOrder,null,true).FirstOrDefault(s => s is procedure_header); - if (pt != null) - { - AddError(get_location(pt), "PROCEDURE_TYPE_SHOULD_BE_REPLACED_BY_TYPE_NAME_IN_THIS_CONTEXT"); - } - // SSM 11/05/15 sugared node - var l = new List(); - l.Add(new ident("?System")); - l.Add(new ident("Collections")); - l.Add(new ident("Generic")); - l.Add(new ident("IEnumerable")); - var tr = new template_type_reference(new named_type_reference(l), - new template_param_list(_sequence_type.elements_type, _sequence_type.elements_type.source_context), - _sequence_type.source_context); - visit(tr); - } - - public override void visit(SyntaxTree.modern_proc_type _modern_proc_type) // сахарный узел - { - if (_modern_proc_type.res != null) - { - var l = new List(); - l.Add(new ident("?System")); - l.Add(new ident("Func")); - var t = new template_param_list(); - if (_modern_proc_type.aloneparam != null) - t.Add(_modern_proc_type.aloneparam); - if (_modern_proc_type.el != null) - { - var en = _modern_proc_type.el; - if (en.enumerators.Count == 1) - AddError(get_location(en.enumerators[0].name), "ONE_TYPE_PARAMETER_MUSTBE_WITHOUT_PARENTHESES"); - for (int i = 0; i < en.enumerators.Count; i++) - { - if (en.enumerators[i].value != null) - AddError(get_location(en.enumerators[i].name), "ONE_TKIDENTIFIER"); - - if (!(en.enumerators[i].name is named_type_reference)) - AddError(get_location(en.enumerators[i].name), "ONE_TKIDENTIFIER"); - - t.Add(en.enumerators[i].name); // ??????????????? - } - } - t.Add(_modern_proc_type.res, _modern_proc_type.res.source_context); - t.source_context = _modern_proc_type.source_context; - var ttr = new template_type_reference(new named_type_reference(l), t, _modern_proc_type.source_context); - visit(ttr); - } - else if (_modern_proc_type.aloneparam != null || _modern_proc_type.el != null) - { - var l = new List(); - l.Add(new ident("?System")); - l.Add(new ident("Action")); - var t = new template_param_list(); - if (_modern_proc_type.aloneparam != null) - t.Add(_modern_proc_type.aloneparam); - if (_modern_proc_type.el != null) - { - var en = _modern_proc_type.el; - if (en.enumerators.Count == 1) - AddError(get_location(en.enumerators[0].name), "ONE_TYPE_PARAMETER_MUSTBE_WITHOUT_PARENTHESES"); - for (int i = 0; i < en.enumerators.Count; i++) - { - - if (en.enumerators[i].value != null) - AddError(get_location(en.enumerators[i].name), "ONE_TKIDENTIFIER"); - - if (!(en.enumerators[i].name is named_type_reference)) - AddError(get_location(en.enumerators[i].name), "ONE_TKIDENTIFIER"); - - t.Add(en.enumerators[i].name); - } - } - t.source_context = _modern_proc_type.source_context; - var ttr = new template_type_reference(new named_type_reference(l), t, _modern_proc_type.source_context); - visit(ttr); - } - else - { - var l = new List(); - l.Add(new ident("?System")); - l.Add(new ident("Action")); - var ntr = new named_type_reference(l); - visit(ntr); - } - } - - // Это в куче мест надо. Потому что либо compiled_type_node, либо compiled_generic_instance_type_node - // compiled_type_node если в записи A все типы NETовские - // compiled_generic_instance_type_node если в записи A хоть один тип - паскалевский - public Type ConvertSemanticTypeNodeToNETType(type_node tn) - { - if (tn is compiled_generic_instance_type_node) - { - var tnc = (tn as compiled_generic_instance_type_node); - var itnc = tnc.original_generic as compiled_type_node; - var tt = itnc.compiled_type; - if (tt.IsGenericType) - tt = tt.GetGenericTypeDefinition(); - return tt; - } - else if (tn is compiled_type_node) - { - var itnc = (tn as compiled_type_node); - var tt = itnc.compiled_type; - if (tt.IsGenericType) - tt = tt.GetGenericTypeDefinition(); - return tt; - } - return null; - } - - /*expression_list construct_expression_list_for_slice_expr(SyntaxTree.slice_expr sl) - { - // situation = 0 - ничего не пропущено - // situation = 1 - пропущен from - // situation = 2 - пропущен to - // situation = 3 - пропущены from и to - // Пропущенность кодируется тем, что в соответствующем поле - int.MaxValue - // step может просто отсутствовать - это параметр по умолчанию в SystemSlice - - int situation = 0; - - if ((sl.from is int32_const) && (sl.from as int32_const).val == int.MaxValue) - situation += 1; - if ((sl.to is int32_const) && (sl.to as int32_const).val == int.MaxValue) - situation += 2; - - var el = new SyntaxTree.expression_list(); - el.Add(new int32_const(situation)); - el.Add(sl.from); // Это плохо - считается 2 раза. Надо делать semantic_expr_node !!!? Нет!!! - // Если там будет лямбда, то не будет работать - известно, что semantic_expr_node не работает с лямбдами - // т.к. они несколько раз обходят код. - el.Add(sl.to); - if (sl.step != null) - el.Add(sl.step); - - return el; - }*/ - - // frninja 04/03/16 - для yield - - // frninja 06/06/16 - фикс для видимости private методов и полей с классов в том же модуле - private unit_node GetUnknownIdentUnit(definition_node dn) - { - if (dn is class_field) - { - return ((dn as class_field).cont_type.comprehensive_namespace != null) - ? (dn as class_field).cont_type.comprehensive_namespace.cont_unit - : null; - } - else if (dn is common_method_node) - { - return ((dn as common_method_node).cont_type.comprehensive_namespace != null) - ? (dn as common_method_node).cont_type.comprehensive_namespace.cont_unit - : null; - } - else if (dn is common_property_node) - { - return ((dn as common_property_node).common_comprehensive_type.comprehensive_namespace != null) - ? (dn as common_property_node).common_comprehensive_type.comprehensive_namespace.cont_unit - : null; - } - - return null; - } - // end frninja 06/06/16 - - private bool CheckIsStaticName(definition_node dn) - { - if (dn is class_field && (dn as class_field).polymorphic_state == SemanticTree.polymorphic_state.ps_static) - return true; - - if (dn is common_method_node && (dn as common_method_node).polymorphic_state == SemanticTree.polymorphic_state.ps_static) - return true; - - if (dn is common_property_node && (dn as common_property_node).polymorphic_state == SemanticTree.polymorphic_state.ps_static) - return true; - - if (dn is compiled_function_node && (dn as compiled_function_node).polymorphic_state == SemanticTree.polymorphic_state.ps_static) - return true; - - if (dn is compiled_property_node && (dn as compiled_property_node).polymorphic_state == SemanticTree.polymorphic_state.ps_static) - return true; - - return false; - } - - private bool CheckUnknownIdentNeedsClassCapture(SyntaxTree.yield_unknown_ident _unk, out bool isStaticIdent) - { - - string Consts__Self = YieldHelpers.YieldConsts.Self; - - // Find semantic class containing iterator (yield-method) with unknown ident - var iteratorContainingClass = context._ctn.fields.Where(f => f.name == Consts__Self).FirstOrDefault()?.type; - //var iteratorContainingClass = context._cmn.types.Where(t => t.name == _unk.ClassName.name).First(); - - isStaticIdent = false; - - if (iteratorContainingClass != null) - { - // Search for unknown ident in class - var found = iteratorContainingClass.find(_unk.UnknownID.name); - if (found != null) - { - // class_field - поле класса - // common_method_node - метод класса - // common_property_node - свойство класса - - // че там с .NET как базовым? - // compiled_function_node - метод базового .NET класса - // compiled_property_node - свойство базового .NET класса - - // че с классом из другого модуля? - // то же что и с классом из этого же - var found_unit = found.FirstOrDefault(); - isStaticIdent = CheckIsStaticName(found_unit.sym_info); - - if (found_unit.sym_info is class_field - || found_unit.sym_info is class_constant_definition // SSM #2152 - || found_unit.sym_info is common_method_node - || found_unit.sym_info is common_property_node - || found_unit.sym_info is compiled_function_node - || found_unit.sym_info is compiled_property_node) - { - if (!isStaticIdent && _unk.IsYieldInStaticMethod) - return false; - - // frninja 06/06/16 - фиксим private того же модуля - if ((iteratorContainingClass is common_type_node) - && this.GetUnknownIdentUnit(found_unit.sym_info) == - (((iteratorContainingClass as common_type_node).comprehensive_namespace != null) - ? (iteratorContainingClass as common_type_node).comprehensive_namespace.cont_unit - : null)) - { - return true; - } - else if (found_unit.access_level != access_level.al_private) - { - return true; - } - } - - // common_namespace_function_node - глобальный метод - - } - } - - return false; - } - - private dot_node CaptureUnknownIdent(yield_unknown_ident unk, bool isStaticIdent = false) - { - if (isStaticIdent) - { - return new dot_node(unk.ClassName, unk.UnknownID); - } - string Consts__Self = YieldHelpers.YieldConsts.Self; - - return new dot_node(new dot_node(new ident("self"), new ident(Consts__Self)), unk.UnknownID); - } - - private SyntaxTree.addressed_value_funcname ProcessUnknownIdent(yield_unknown_ident unk) - { - bool isStaticIdent; - if (CheckUnknownIdentNeedsClassCapture(unk, out isStaticIdent)) - { - var uid = CaptureUnknownIdent(unk, isStaticIdent); - return uid; - } - else - { - return unk.UnknownID; - } - } - - public override void visit(SyntaxTree.yield_node yn) - { - // надо что то сгенерировать, иначе выдается ложное предупреждение о недостижимом коде и проч. - /*var ass = new assign("Result", new nil_const()); - visit(ass); - var pc = new procedure_call("exit"); - visit(pc);*/ - } - - // frninja - захват полей класса для yield - public override void visit(SyntaxTree.yield_unknown_ident _unk) - { - ProcessUnknownIdent(_unk).visit(this); - } - - public override void visit(SyntaxTree.yield_unknown_expression_type _unk_expr) - { - // Отвечает за типизацию всех переменных с автовыведением типа - // Пробую сделать по-другому: перевести в auto_type и потом на присваивании перехватить - var t = new semantic_type_node(new auto_type(get_location(_unk_expr))); - t.visit(this); - } - - // frninja 29/05/16 - выявляем тип перемнной в foreach - public override void visit(SyntaxTree.yield_unknown_foreach_type _unk) - { - var t = new semantic_type_node(new ienumerable_auto_type(get_location(_unk))); - t.visit(this); - } - - public override void visit(SyntaxTree.dot_question_node dqn) - { - // a?.b - AddError(get_location(dqn), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", dqn.GetType().Name); - //var q = ConvertToQCE(dqn); - //visit(q); - } - - public override void visit(SyntaxTree.semantic_check_sugared_statement_node st) - { - /*if (st.visited) - return; - st.visited = true;*/ - if (st.typ as System.Type == typeof(SyntaxTree.assign_tuple)) - { - var vars = st.lst[0] as SyntaxTree.addressed_value_list; - var expr = st.lst[1] as SyntaxTree.expression; - semantic_check_assign_tuple(vars, expr); - } - else if (st.typ as System.Type == typeof(SyntaxTree.assign_var_tuple)) - { - var idents = st.lst[0] as SyntaxTree.ident_list; - var expr = st.lst[1] as SyntaxTree.expression; - semantic_check_assign_var_tuple(idents, expr); - } - else if (st.typ as System.Type == typeof(SyntaxTree.loop_stmt)) - { - var expr = st.lst[0] as SyntaxTree.expression; - semantic_check_loop_stmt(expr); - } - else if (st.typ as System.Type == typeof(SyntaxTree.foreach_stmt) && st.lst.Count == 3) // для NewRange Visitorа. Если будет перекрытие, то надоделать новые типы-маркеры - { - var expr = st.lst[0] as SyntaxTree.diapason_expr_new; - var td = st.lst[1] as SyntaxTree.type_definition; - var id = st.lst[2] as SyntaxTree.ident; - semantic_check_for_new_range(expr, td, id); - } - /*else if (st.typ as System.Type == typeof(SyntaxTree.foreach_stmt) && st.lst.Count == 1) // для a.Indices. Пока непонятно, где описывать тип-маркер - { - var expr = st.lst[0] as SyntaxTree.expression; - semantic_check_for_indices(expr); - }*/ - // Patterns - else if (st.typ is SemanticCheckType.MatchedExpression) // Это безобразие - SemanticCheckType в TreeHelper.cs помещать!!! - { - var expr = st.lst[0] as expression; - CheckMatchedExpression(expr); - } - else if (st.typ is SemanticCheckType.MatchedExpressionAndType) - { - var expr = st.lst[0] as expression; - var type = st.lst[1] as type_definition; - CheckIfCanBeMatched(expr, type); - } - else if (st.typ is SemanticCheckType.MatchedExpressionAndExpression) - { - var matchedExpr = st.lst[0] as expression; - var patternExpr = st.lst[1] as expression; - CheckIfCanBeMatched(matchedExpr, patternExpr); - } - else if (st.typ is SemanticCheckType.MatchedTuple) - { - var tuple = st.lst[0] as expression; - var length = st.lst[1] as int32_const; - CheckIfCanBeMatched(tuple, length); - } - // !Patterns - // Slices - else if (st.typ is SemanticCheckType.SliceAssignmentTypeCompatibility) - { - var to = st.lst[0] as expression; - var from = st.lst[1] as expression; - var mc = st.lst[2] as method_call; - semantic_check_slice_assignment_types(to, from, mc); - } - // !Slices - else - { - AddError(get_location(st), "MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}", (st.typ as System.Type)?.Name ?? "Unknown"); - } - ret.reset(); // обязательно очистить - этот узел в семантику ничего не должен приносить! - ReplaceUsingParent(st, new PascalABCCompiler.SyntaxTree.empty_statement()); - } - - public override void visit(SyntaxTree.semantic_check_sugared_var_def_statement_node st) - { - if (st.typ as System.Type == typeof(SyntaxTree.assign_var_tuple)) - { - var idents = st.lst[0] as SyntaxTree.ident_list; - var expr = st.lst[1] as SyntaxTree.expression; - semantic_check_assign_var_tuple(idents, expr); - } - else - { - AddError(get_location(st), "MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}", (st.typ as System.Type)?.Name ?? "Unknown"); - } - ret.reset(); // обязательно очистить - этот узел в семантику ничего не должен приносить! - } - - public override void visit(SyntaxTree.sugared_expression ex) - { - /*if (ex.sugared_expr is SyntaxTree.tuple_node) - { - semantic_check_tuple(ex.sugared_expr as SyntaxTree.tuple_node); - } - else*/ - { - AddError(get_location(ex), "MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}", ex.sugared_expr.GetType().Name); - } - - ProcessNode(ex.new_expr); // обойти десахарное выражение - обязательно ProcessNode - visit нельзя! - } - - public method_call ToNullable(expression e) - { - var dn = new dot_node(new ident("PABCSystem"), new ident("DQNToNullable")); - return new method_call(dn, new expression_list(e), e.source_context); - } - - public override void visit(SyntaxTree.sugared_addressed_value av) - { - if (av.sugared_expr is SyntaxTree.diapason_expr_new) - { - semantic_check_method_call_as_diapason_expr(av.new_addr_value as SyntaxTree.method_call); - } - else if (av.sugared_expr is SyntaxTree.slice_expr) // и slice_expr_question - { - semantic_check_method_call_as_slice_expr(av.new_addr_value as SyntaxTree.method_call); - } - else if (av.sugared_expr is SyntaxTree.dot_question_node) - { - var qce = av.new_addr_value as SyntaxTree.question_colon_expression; - var av_cs = convert_strong(qce.ret_if_false); - try_convert_typed_expression_to_function_call(ref av_cs); - if (!type_table.is_with_nil_allowed(av_cs.type)) - { - var dn = new dot_node(new ident("PABCSystem"), new ident("DQNToNullable")); - (av.new_addr_value as SyntaxTree.question_colon_expression).ret_if_false - = new method_call(dn, new expression_list((av.new_addr_value as SyntaxTree.question_colon_expression).ret_if_false), av.source_context); - - /*var avqce = av.new_addr_value as SyntaxTree.question_colon_expression; - //var dn = new dot_node(new ident("PABCSystem"), new ident("DQNToNullable")); - avqce.ret_if_false = ToNullable(avqce.ret_if_false); - //new method_call(dn, new expression_list(avqce.ret_if_false), av.source_context);*/ - } - semantic_check_dot_question(av.new_addr_value as SyntaxTree.question_colon_expression); - } - else if (av.sugared_expr is SyntaxTree.bin_expr) // Это пришло от i in (2..5). Плохо, что могут быть другие bin_expr - { - semantic_check_method_call_as_inrange_expr(av.new_addr_value as SyntaxTree.method_call); - } - else - { - AddError(get_location(av), "MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}", av.sugared_expr.GetType().Name); - } - - ProcessNode(av.new_addr_value); // обойти десахарное - } - - private void CheckUnpacking(expression ex, out expression_node sem_ex, out bool IsTuple, out bool IsSequence, int countvars, syntax_tree_node stn) - { - sem_ex = convert_strong(ex); - sem_ex = convert_if_typed_expression_to_function_call(sem_ex); - var t = ConvertSemanticTypeNodeToNETType(sem_ex.type); - if (t == null) - AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); - IsTuple = false; - IsSequence = false; - if (t.FullName.StartsWith("System.Tuple")) - IsTuple = true; - if (!IsTuple) - { - if (t.Name.Equals("IEnumerable`1") || t.GetInterface("IEnumerable`1") != null) - IsSequence = true; - } - if (!IsTuple && !IsSequence) - { - AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); - } - if (IsTuple) - { - if (countvars > t.GetGenericArguments().Count()) - AddError(get_location(stn), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT"); - } - } - - private addressed_value UnpackingExpr(int i, bool IsTuple, bool IsSequence, string tname) - { - addressed_value dn = null; - if (IsTuple) - dn = new dot_node(new ident(tname), new ident("Item" + (i + 1).ToString())); - else if (IsSequence) - { - dn = new dot_node(new ident(tname), new ident("ElementAt")); - var pars = new SyntaxTree.expression_list(new int32_const(i)); - - dn = new method_call(dn, pars); - } - return dn; - } - - public override void visit(SyntaxTree.assign_tuple asstup) // сахарный узел - { - AddError(get_location(asstup), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", asstup.GetType().Name); - // На семантике тяжело делать сахар с определениями переменных, которые потом захватываются лямбдами: var (m,n) := t; ArrGen(x->x+m); - // Перенесено на синтаксис с генерацией узла semantic_ith_element_of, разворачивающегося на семантике - - /*CheckUnpacking(asstup.expr, out var sem_ex, out var IsTuple, out var IsSequence, asstup.vars.variables.Count(), asstup.vars); - var sem_node = new SyntaxTree.semantic_addr_value(sem_ex); // чтобы два раза не делать convert_strong - - //semantic_check_assign_tuple(asstup.vars, asstup.expr); - - var tname = "#temp_var" + UniqueNumStr(); - - var tt = new var_statement(new ident(tname), sem_node; // тут semantic_addr_value хранит на самом деле expr - просто неудачное название - var st = new statement_list(); - st.Add(tt); - - var n = asstup.vars.variables.Count(); - for (var i = 0; i < n; i++) - { - var a = new assign(asstup.vars.variables[i], - //new dot_node(new ident(tname), new ident("Item" + (i + 1).ToString())), - UnpackingExpr(i, IsTuple, IsSequence, tname), - Operators.Assignment, - asstup.vars.variables[i].source_context); - st.Add(a); - } - visit(st);*/ - } - - public override void visit(SyntaxTree.assign_var_tuple assvartup) // сахарный узел - { - AddError(get_location(assvartup), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", assvartup.GetType().Name); - // На семантике тяжело делать сахар с определениями переменных, которые потом захватываются лямбдами: var (m,n) := t; ArrGen(x->x+m); - - //CheckUnpacking(assvartup.expr, out var sem_ex, out var IsTuple, out var IsSequence, assvartup.idents.idents.Count(), assvartup.idents); - - /*var sem_ex = convert_strong(assvartup.expr); - sem_ex = convert_if_typed_expression_to_function_call(sem_ex); - var t = ConvertSemanticTypeNodeToNETType(sem_ex.type); - if (t == null) - AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); - - var IsTuple = false; - var IsSequence = false; - if (t.FullName.StartsWith("System.Tuple")) - IsTuple = true; - if (!IsTuple) - { - if (t.Name.Equals("IEnumerable`1") || t.GetInterface("IEnumerable`1") != null) - IsSequence = true; - } - if (!IsTuple && !IsSequence) - { - AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); - } - - if (IsTuple) - { - var nn = assvartup.idents.idents.Count(); - if (nn > t.GetGenericArguments().Count()) - AddError(get_location(assvartup.idents), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT"); - }*/ - - - // В зависимости от типа выражения по-разному распаковывать - // Распаковывать можно только для кортежей или последовательностей - // if IsTuple ... - // if IsSequence ... - // else AddError(либо кортеж либо последовательность) - - /*var sem_node = new SyntaxTree.semantic_addr_value(sem_ex); // чтобы два раза не делать convert_strong - - //semantic_check_assign_var_tuple(assvartup.idents, sem_node); - - var tname = "#temp_var" + UniqueNumStr(); - - var tt = new var_statement(new ident(tname), sem_node); - - var sl = new statement_list(); - sl.Add(new SyntaxTree.empty_statement()); - sl.Add(tt); - - var n = assvartup.idents.idents.Count(); - for (var i = 0; i < n; i++) - { - var rr = assvartup.idents.idents[i] as ident; - var a = new var_statement(rr, - //new dot_node(new ident(tname),new ident("Item" + (i + 1).ToString())), - //dn, - UnpackingExpr(i, IsTuple, IsSequence, tname), - assvartup.idents.idents[i].source_context - ); - sl.Add(a); - } - //assvartup.sl = sl; - ReplaceStatementUsingParent(assvartup, sl.list); // добавляем пустой оператор чтобы здесь его пропустить, а обходить следующие - //sl.IsInternal = true; - //ReplaceUsingParent(assvartup, sl); // меняем один оператор на один. На 2 и 3 проходе лямбды обходится именно он - //visit_statement_list_internal(sl);*/ - } - - public override void visit(semantic_ith_element_of ith) - { - var sem_ex = convert_strong(ith.id); - sem_ex = convert_if_typed_expression_to_function_call(sem_ex); - var t = ConvertSemanticTypeNodeToNETType(sem_ex.type); - if (t == null) - AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); - var IsTuple = false; - var IsSequence = false; - if (t.FullName.StartsWith("System.Tuple")) - IsTuple = true; - if (!IsTuple) - { - if (t.Name.Equals("IEnumerable`1") || t.GetInterface("IEnumerable`1") != null) - IsSequence = true; - } - if (!IsTuple && !IsSequence) - { - AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); - } - - //addressed_value dn = null; - var i = (ith.index as int32_const).val; - if (IsTuple) - { - var dn = new dot_node(ith.id.TypedClone(), new ident("Item" + (i + 1).ToString())); - ReplaceUsingParent(ith, dn); - visit(dn); - } - else if (IsSequence) - { - var dn = new dot_node(ith.id.TypedClone(), new ident("ElementAt")); - var pars = new SyntaxTree.expression_list(new int32_const(i)); - var mc = new method_call(dn, pars); - ReplaceUsingParent(ith, mc); - visit(mc); - } - } - - - public override void visit(var_tuple_def_statement vtd) - { - AddError(get_location(vtd), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", vtd.GetType().Name); - // На семантике тяжело делать сахар с определениями переменных, которые потом захватываются лямбдами: var (m,n) := t; ArrGen(x->x+m); - - // Состоит из var_def_statements. Некоторые являются var_tuple_def_statement - // Их надо найти и сделать несколько секций variable_definitions - без семантических проверок. - // Каждую var_tuple_def_statement надо заменить на assign_var_tuple - одну на секцию variable_definitions - // А потом оставшаяся часть визитора сделает семантические проверки - - /*CheckUnpacking(vtd.inital_value, out var sem_ex, out var IsTuple, out var IsSequence, vtd.vars.idents.Count(), vtd.vars); - var sem_node = new SyntaxTree.semantic_addr_value(sem_ex); // чтобы два раза не делать convert_strong - - //semantic_check_assign_var_tuple(vtd.vars, vtd.inital_value); - - var tname = "#temp_var" + UniqueNumStr(); - //var vd = new List(); - //vd.Add(new semantic_check_sugared_var_def_statement_node(typeof(assign_var_tuple), new List { vtd.vars, vtd.inital_value }, vtd.source_context)); // Это нужно для проверок на этапе преобразования в семантику - //visit(vd[0]); - - var tt1 = new var_def_statement(new ident(tname), vtd.inital_value); - ProcessNode(tt1); - var nn = vtd.vars.idents.Count(); - for (var i = 0; i < nn; i++) - { - var a = new var_def_statement(vtd.vars.idents[i], - UnpackingExpr(i, IsTuple, IsSequence, tname), - //new dot_node(new ident(tname), new ident("Item" + (i + 1).ToString())), - vtd.vars.idents[i].source_context); - ProcessNode(a); - }*/ - } - - public void ReplaceVarTupleDefStatementUsingParent(var_tuple_def_statement from, IEnumerable to) - { - foreach (var x in to) - x.Parent = from.Parent; - var sl = from.Parent as variable_definitions; - if (sl != null) - { - sl.ReplaceInList(from, to); - } - } - - - - public override void visit(SyntaxTree.slice_expr sl) // сахарный узел - { - AddError(get_location(sl), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", sl.GetType().Name); - - /* - // Преобразуется в вызов a.SystemSlice(situation,from,to,step) - // Тип a должен быть array of T, List или string - semcheck(sl); - - // Действия уровня синтаксиса. Можно вынести на синтаксический уровень как desugaring для сахарного узла - var el = construct_expression_list_for_slice_expr(sl); - var mc = new method_call(new dot_node(sl.v, new ident("SystemSlice", sl.v.source_context), sl.v.source_context), el, sl.source_context); - - visit(mc);*/ - } - - public override void visit(SyntaxTree.slice_expr_question sl) // сахарный узел - { - AddError(get_location(sl), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", sl.GetType().Name); - /* - // Преобразуется в вызов a.SystemSlice(situation,from,to,step) - // Тип a должен быть array of T, List или string - semcheck(sl); - - var el = construct_expression_list_for_slice_expr(sl); - var mc = new method_call(new dot_node(sl.v, new ident("SystemSliceQuestion", sl.v.source_context), sl.v.source_context), el, sl.source_context); - - visit(mc);*/ - } - } + } + + foreach (parameter par in fn.parameters) + { + //(ssyy) Интересно, зачем это. + concrete_parameter_type cpt = + (par.parameter_type == SemanticTree.parameter_type.var) ? + concrete_parameter_type.cpt_var : + concrete_parameter_type.cpt_none; + common_parameter c_p = new common_parameter(par.name, + par.parameter_type, gen_constr, cpt, null); + c_p.type = par.type; + c_p.set_param_is_params(par.is_params); + c_p.inital_value = par.inital_value; + gen_constr.parameters.AddElement(c_p); + c_p.default_value = par.default_value; + } + + base_function_call bfc; + + if (mconstr != null) + { + common_constructor_call c1 = new common_constructor_call(mconstr, null); + c1._new_obj_awaited = false; + bfc = c1; + } + else + { + compiled_constructor_call c2 = new compiled_constructor_call(pconstr, null); + c2._new_obj_awaited = false; + bfc = c2; + } + foreach (parameter p in gen_constr.parameters) + { + bfc.parameters.AddElement( + create_variable_reference(p, null)); + } + statements_list snlist = new statements_list(null); + snlist.statements.AddElement(bfc); + snlist.statements.AddElement(new empty_statement(null)); + gen_constr.function_code = snlist; + context.leave_block(); + if (fn.parameters.Count == 0 || fn.parameters[0].default_value != null) + { + _ctn.has_default_constructor = true; + } + } + } + } + } + //\ssyy + + //ssyy + public void generate_inherited_from_base_and_interface_function(common_type_node ctype, function_node func) + { + common_method_node gen_func = context.create_function(func.name, null) as common_method_node; + gen_func.polymorphic_state = SemanticTree.polymorphic_state.ps_common; + gen_func.newslot_awaited = true; + gen_func.is_final = true; + gen_func.is_overload = true; + gen_func.field_access_level = SemanticTree.field_access_level.fal_public; + gen_func.return_value_type = func.return_value_type; + //gen_func.return_variable = func.retu + + foreach (parameter par in func.parameters) + { + concrete_parameter_type cpt = + (par.parameter_type == SemanticTree.parameter_type.value) ? + concrete_parameter_type.cpt_const : + concrete_parameter_type.cpt_var; + common_parameter c_p = new common_parameter(par.name, + par.parameter_type, gen_func, cpt, null); + c_p.type = par.type; + c_p.set_param_is_params(par.is_params); + c_p.inital_value = par.inital_value; + gen_func.parameters.AddElement(c_p); + } + + local_variable lv = new local_variable(compiler_string_consts.self_word, gen_func.cont_type, gen_func, null); + gen_func.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(lv)); + gen_func.self_variable = lv; + + base_function_call bfc; + this_node tn = null; + + common_method_node commn = func as common_method_node; + if (commn != null) + { + tn = new this_node(commn.comperehensive_type as type_node, null); + bfc = new common_method_call(commn, tn, null); + } + else + { + compiled_function_node compn = func as compiled_function_node; + tn = new this_node(compn.comperehensive_type as type_node, null); + bfc = new compiled_function_call(compn, tn, null); + } + + foreach (parameter p in gen_func.parameters) + { + bfc.parameters.AddElement( + create_variable_reference(p, null)); + } + + //Это запретит чистку стека + bfc.last_result_function_call = true; + + statements_list snlist = new statements_list(null); + snlist.statements.AddElement(bfc); + snlist.statements.AddElement(new empty_statement(null)); + gen_func.function_code = snlist; + context.pop_top_function(); + //context.leave_block(); + } + //\ssyy + + private Dictionary WaitedRefTypes = new Dictionary(); + internal ref_type_node GetWaitedRefType(string name, location loc) + { + ref_type_node rtn = null; + if (WaitedRefTypes.TryGetValue(name, out rtn)) + return rtn; + rtn = new ref_type_node(null); + rtn.PointedTypeName = name; + rtn.loc = loc; + WaitedRefTypes.Add(name, rtn); + return rtn; + } + + internal List RefTypesForCheckPointersTypeForDotNetFramework = new List(); + void ProcessRefTypesForCheckPointersTypeForDotNetFramework() + { + foreach (ref_type_node rtn in RefTypesForCheckPointersTypeForDotNetFramework) + if (SemanticRules.StrongPointersTypeCheckForDotNet) + CheckPointersTypeForDotNetFramework(rtn.pointed_type, rtn.loc); + RefTypesForCheckPointersTypeForDotNetFramework.Clear(); + } + internal void CheckWaitedRefTypes(type_node tn) + { + ref_type_node rtn = null; + if (WaitedRefTypes.TryGetValue(tn.name, out rtn)) + { + if (SemanticRules.StrongPointersTypeCheckForDotNet) + RefTypesForCheckPointersTypeForDotNetFramework.Add(rtn); + rtn.SetPointedType(tn); + WaitedRefTypes.Remove(tn.name); + } + } + + internal void EnterTypeDeclarationsSection() + { + type_section_converting = true; + } + + internal void LeaveTypeDeclarationsSection() + { + type_section_converting = false; + if (context.types_predefined.Count > 0 && !context.namespace_converted) + { + AddError(context.types_predefined[0].loc, "NO_TYPE_{0}_DEFINITION", context.types_predefined[0].name); + } + foreach (string Name in WaitedRefTypes.Keys) + WaitedRefTypes[Name].SetPointedType(find_type(Name, WaitedRefTypes[Name].loc)); + foreach (ref_type_node rtn in WaitedRefTypes.Values) + CheckForCircularityInPointers(rtn, rtn.pointed_type,rtn.loc); + ProcessRefTypesForCheckPointersTypeForDotNetFramework(); + WaitedRefTypes.Clear(); + } + + internal void ProcessCheckPointersInRecord() + { + ProcessRefTypesForCheckPointersTypeForDotNetFramework(); + } + + public override void visit(SyntaxTree.c_scalar_type node) + { + Type t = null; + switch (node.scalar_name) + { + case SyntaxTree.c_scalar_type_name.tn_void: + t = typeof(void); + break; + case SyntaxTree.c_scalar_type_name.tn_char: + t = typeof(char); + break; + case SyntaxTree.c_scalar_type_name.tn_double: + t = typeof(double); + break; + case SyntaxTree.c_scalar_type_name.tn_float: + t = typeof(float); + break; + case SyntaxTree.c_scalar_type_name.tn_int: + t = (node.sign == SyntaxTree.c_scalar_sign.unsigned) ? + typeof(UInt32) : + typeof(Int32); + break; + case SyntaxTree.c_scalar_type_name.tn_long: + case SyntaxTree.c_scalar_type_name.tn_long_int: + t = (node.sign == SyntaxTree.c_scalar_sign.unsigned) ? + typeof(UInt64) : + typeof(Int64); + break; + case SyntaxTree.c_scalar_type_name.tn_short: + case SyntaxTree.c_scalar_type_name.tn_short_int: + t = typeof(Int16); + break; + } + ret.return_value(compiled_type_node.get_type_node(t)); + } + + public override void visit(SyntaxTree.c_module node) + { + string namespace_name = ""; + location loc = null; + // if (_program_module.program_name != null) + // { + // namespace_name = _program_module.program_name.prog_name.name; + // loc = get_location(_program_module.program_name.prog_name); + // if (namespace_name.ToLower() != System.IO.Path.GetFileNameWithoutExtension(_program_module.file_name).ToLower()) + // throw new ProgramNameMustBeEqualProgramFileName(loc); + // } + + + _compiled_unit = new common_unit_node(); + + _compiled_unit.compiler_directives = ConvertDirectives(node); + //PrepareDirectives(_compiled_unit.compiler_directives); + + //using_list.AddRange(interface_using_list); + //weak_node_test_and_visit(_program_module.using_namespaces); + //weak_node_test_and_visit(node.used_units); + + //compiled_main_unit=new unit_node(); + //SymbolTable.Scope[] used_units=new SymbolTable.Scope[used_assemblyes.Count+1]; + + SymbolTable.Scope[] used_units = build_referenced_units(referenced_units,true); + + _compiled_unit.scope = convertion_data_and_alghoritms.symbol_table.CreateUnitInterfaceScope(used_units, namespace_name); + + common_namespace_node cnsn = context.create_namespace(namespace_name, _compiled_unit, _compiled_unit.scope, loc); + cnsn.is_main = true; + //compiled_program=new program_node(); + //compiled_program.units.Add(compiled_main_unit); + + reset_for_interface(); + + UpdateUnitDefinitionItemForUnit(_compiled_unit); + + //_program_module.program_block.visit(this); + //hard_node_test_and_visit(_program_module.program_block); + //context.check_labels(context.converted_namespace.labels); + + //TODO: Доделать. + //common_namespace_function_node main_function = new common_namespace_function_node(compiler_string_consts.temp_main_function_name, + // null, null, cnsn, null); + //main_function.function_code = context.code; + //cnsn.functions.AddElement(main_function); + + weak_node_test_and_visit(node.defs); + + bool main_not_found = true; + foreach (function_node fn in cnsn.functions) + { + if (fn.name == compiler_string_consts.c_main_function_name) + { + _compiled_unit.main_function = fn as common_namespace_function_node; + //context.apply_special_local_vars(_compiled_unit.main_function); + main_not_found = false; + break; + } + } + if (main_not_found) + { + AddError(get_location(node), "NO_MAIN_FUNCTION"); + } + + context.leave_block(); + + //_compiled_unit.main_function = main_function; + + } + + public override void visit(SyntaxTree.declarations_as_statement node) + { + //throw new NotSupportedError(get_location(node)); + node.defs.visit(this); + return_value(new empty_statement(null)); + } + public override void visit(SyntaxTree.array_size node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.enumerator node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.enumerator_list node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.c_for_cycle node) + { + //throw new NotSupportedError(get_location(node)); + location loc1 = get_location(node.expr1); + statements_list head_stmts = new statements_list(loc1); + convertion_data_and_alghoritms.statement_list_stack_push(head_stmts); + //statement_node sn_init = convert_weak((SyntaxTree.statement)node.expr1); // SSM 12/06/15 - всё равно c-узлы никому не нужны + statement_node sn_init = convert_weak(node.expr1); // SSM 12/06/15 + expression_node sn_cond = convert_weak(node.expr2); + //statement_node sn_next = convert_weak((SyntaxTree.statement)node.expr3); // SSM 12/06/15 + statement_node sn_next = convert_weak(node.expr3); // SSM 12/06/15 + + CheckToEmbeddedStatementCannotBeADeclaration(node.stmt); + + for_node fn = new for_node(sn_init, sn_cond, null, sn_next, null, get_location(node)); + context.cycle_stack.push(fn); + + statements_list slst = new statements_list(get_location(node.stmt)); + convertion_data_and_alghoritms.statement_list_stack_push(slst); + + context.enter_code_block_with_bind(); + fn.body = convert_strong(node.stmt); + context.leave_code_block(); + + slst = convertion_data_and_alghoritms.statement_list_stack.pop(); + if (slst.statements.Count > 0 || slst.local_variables.Count > 0) + { + slst.statements.AddElement(fn.body); + fn.body = slst; + } + + context.cycle_stack.pop(); + + head_stmts = convertion_data_and_alghoritms.statement_list_stack.pop(); + head_stmts.statements.AddElement(fn); + return_value(head_stmts); + + /*slst = convertion_data_and_alghoritms.statement_list_stack.pop(); + if (slst.statements.Count > 0 || slst.local_variables.Count > 0) + { + slst.statements.AddElement(fn.body); + fn.body = slst; + } + + context.cycle_stack.pop();*/ + //ret.return_value(slst); + } + public override void visit(SyntaxTree.switch_stmt node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.type_definition_attr node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.type_definition_attr_list node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.lock_stmt node) + { + expression_node lock_object = convert_strong(node.lock_object); + //Нужно ли это??? + if (lock_object.type.semantic_node_type == semantic_node_type.delegated_method) + try_convert_typed_expression_to_function_call(ref lock_object); + if (lock_object.type == null || lock_object.type.is_value_type) + AddError(get_location(node.lock_object), "EXPRESSION_IN_LOCK_STATEMENT_RETURNED_NOT_A_REFERENCE_TYPE", lock_object.type); + CheckToEmbeddedStatementCannotBeADeclaration(node.stmt); + statement_node stmt = convert_strong(node.stmt); + return_value(new lock_statement(lock_object, stmt, get_location(node))); + } + public override void visit(SyntaxTree.compiler_directive_list node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.compiler_directive_if node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.documentation_comment_list node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.documentation_comment_section node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.documentation_comment_tag node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.documentation_comment_tag_param node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.token_taginfo node) + { + throw new NotSupportedError(get_location(node)); + } + public override void visit(SyntaxTree.declaration_specificator node) + { + throw new NotSupportedError(get_location(node)); + } + + public override void visit(SyntaxTree.ident_with_templateparams _ident_with_templateparams) + { + SyntaxTree.expression ex = _ident_with_templateparams.name; + SyntaxTree.ident id_ex = _ident_with_templateparams.name as SyntaxTree.ident; + dot_node dn = _ident_with_templateparams.name as dot_node; + int par_count = _ident_with_templateparams.template_params.params_list.Count; + if (id_ex != null) + { + SymbolInfo type_si = context.find_first(id_ex.name + compiler_string_consts.generic_params_infix + par_count.ToString()); + if (type_si != null) + { + return_value(get_generic_instance(type_si, _ident_with_templateparams.template_params.params_list)); + return; + } + type_si = context.find_first(id_ex.name); + if (type_si != null && type_si.sym_info.general_node_type == general_node_type.template_type) + { + template_class tc = type_si.sym_info as template_class; + List tpars = visit_type_list(_ident_with_templateparams.template_params.params_list); + return_value(instance_any(tc, tpars, get_location(_ident_with_templateparams))); + return; + } + } + else if (dn != null && dn.right is ident) + { + semantic_node sn = convert_semantic_strong(dn.left); + id_ex = dn.right as SyntaxTree.ident; + type_node tn = null; + namespace_node nn = null; + unit_node un = null; + switch (sn.general_node_type) + { + case general_node_type.expression: tn = (sn as expression_node).type; break; + case general_node_type.type_node: tn = sn as type_node; break; + case general_node_type.namespace_node: nn = sn as namespace_node; break; + case general_node_type.unit_node: un = sn as unit_node; break; + default: + AddError(get_location(dn.left), "EXPECTED_ANOTHER_KIND_OF_OBJECT"); break; + } + List type_sil = null; + if (tn != null) + { + type_sil = tn.find_in_type(id_ex.name + compiler_string_consts.generic_params_infix + par_count.ToString()); + } + else if (nn != null) + { + type_sil = nn.find(id_ex.name + compiler_string_consts.generic_params_infix + par_count.ToString()); + } + else if (un != null) + { + type_sil = un.find_only_in_namespace(id_ex.name + compiler_string_consts.generic_params_infix + par_count.ToString()); + } + if (type_sil != null) + { + return_value(get_generic_instance(type_sil?.FirstOrDefault(), _ident_with_templateparams.template_params.params_list)); + return; + } + if (tn != null) + { + type_sil = tn.find_in_type(id_ex.name); + } + else if (nn != null) + { + type_sil = nn.find(id_ex.name); + } + else if (un != null) + { + type_sil = un.find_only_in_namespace(id_ex.name); + } + if (type_sil != null && type_sil.FirstOrDefault().sym_info.general_node_type == general_node_type.template_type) + { + template_class tc = type_sil.FirstOrDefault().sym_info as template_class; + List tpars = visit_type_list(_ident_with_templateparams.template_params.params_list); + return_value(instance_any(tc, tpars, get_location(_ident_with_templateparams))); + return; + } + dot_node dn2 = new dot_node(dn.left, new ident_with_templateparams(dn.right, _ident_with_templateparams.template_params, dn.right.source_context), dn.source_context); + ex = dn2; + } + + expression_node adr = ret.visit(ex); + typed_expression te = adr as typed_expression; + if (te != null) + { + delegated_methods dm = te.type as delegated_methods; + if (dm != null) + { + List ptypes = visit_type_list(_ident_with_templateparams.template_params.params_list); + base_function_call_list bfcl = new base_function_call_list(); + common_method_node cnode; + compiled_function_node comp_node; + function_node fnode; + int generic_count = 0; + foreach (base_function_call bfc in dm.proper_methods) + { + if (bfc.simple_function_node.is_generic_function) + { + generic_count++; + } + } + bool one_function = false; + switch (generic_count) + { + case 0: + AddError(get_location(_ident_with_templateparams), "TRIANGLE_BRACKETS_NOT_ALLOWED_WITH_COMMON_FUNCTIONS"); break; + case 1: + one_function = true; + break; + default: + one_function = false; + break; + } + foreach (base_function_call bfc in dm.proper_methods) + { + if (!bfc.simple_function_node.is_generic_function) + { + continue; + } + switch (bfc.semantic_node_type) + { + case semantic_node_type.common_namespace_function_call: + common_namespace_function_node cnfn = bfc.simple_function_node.get_instance(ptypes, one_function, get_location(_ident_with_templateparams)) as common_namespace_function_node; + if (cnfn != null) + { + bfcl.AddElement(new common_namespace_function_call(cnfn, bfc.location)); + } + break; + case semantic_node_type.common_method_call: + cnode = bfc.simple_function_node.get_instance(ptypes, one_function, get_location(_ident_with_templateparams)) as common_method_node; + if (cnode != null) + { + bfcl.AddElement(new common_method_call(cnode, (bfc as common_method_call).obj, bfc.location)); + } + break; + case semantic_node_type.compiled_function_call: + fnode = bfc.simple_function_node.get_instance(ptypes, one_function, get_location(_ident_with_templateparams)); + cnode = fnode as common_method_node; + if (cnode != null) + { + bfcl.AddElement(new common_method_call(cnode, (bfc as compiled_function_call).obj, bfc.location)); + } + else + { + comp_node = fnode as compiled_function_node; + if (comp_node != null) + { + bfcl.AddElement(new compiled_function_call(comp_node, (bfc as compiled_function_call).obj, bfc.location)); + } + } + break; + case semantic_node_type.common_static_method_call: + case semantic_node_type.compiled_static_method_call: + fnode = bfc.simple_function_node.get_instance(ptypes, one_function, get_location(_ident_with_templateparams)); + cnode = fnode as common_method_node; + if (cnode != null) + { + bfcl.AddElement(new common_static_method_call(cnode, bfc.location)); + } + else + { + comp_node = fnode as compiled_function_node; + if (comp_node != null) + { + bfcl.AddElement(new compiled_static_method_call(comp_node, bfc.location)); + } + } + break; + } + } + if (bfcl.Count == 0) + { + AddError(get_location(_ident_with_templateparams.template_params), "NO_FUNCTIONS_{0}_CAN_BE_USED_WITH_THIS_SPECIFICATION", dm.proper_methods[0].function.name); + } + delegated_methods dm1 = new delegated_methods(); + dm1.proper_methods.AddRange(bfcl); + typed_expression te1 = new typed_expression(dm1, te.location); + return_value(te1); + return; + } + } + if (!(adr is compiled_static_method_call) && !(adr is common_static_method_call) && !(adr is common_namespace_function_call)) + AddError(get_location(_ident_with_templateparams.name), "TRIANGLE_BRACKETS_NOT_AWAITED"); + } + + public override void visit(SyntaxTree.template_type_name node) + { + throw new NotSupportedError(get_location(node)); + } + + public override void visit(SyntaxTree.default_operator _default_operator) + { + type_node tn = ret.visit(_default_operator.type_name); + if (tn == null) + { + AddError(get_location(_default_operator), "TYPE_REFERENCE_EXPECTED"); + } + if (tn == SystemLibrary.SystemLibrary.void_type) + { + AddError(get_location(_default_operator.type_name), "INAVLID_TYPE"); + } + return_value(new default_operator_node(tn, get_location(_default_operator))); + //throw new NotSupportedError(get_location(_default_operator)); + } + + public override void visit(SyntaxTree.bracket_expr _bracket_expr) + { + _bracket_expr.expr.visit(this); + } + + public override void visit(SyntaxTree.attribute _attribute) + { + + } + + public override void visit(SyntaxTree.attribute_list _attribute_list) + { + + } + + public override void visit(SyntaxTree.simple_attribute_list _simple_attribute_list) + { + + } + + public override void visit(closure_substituting_node _closure_substituting_node) + { + visit(_closure_substituting_node.substitution); + } + + public void MaybeConvertFunctionLambdaDefinitionToProcedureLambdaDefinition(function_lambda_definition _function_lambda_definition) + { + // SSM 23/07/16 - вроде сделал лучше в LambdaHelper.InferTypesFromVarStmt, но пока везде удалять вызов этой функции не решаюсь - лень тестировать + // SSM 18/04/16 попытка разрешить x->Print(x) + var stl = _function_lambda_definition.proc_body as SyntaxTree.statement_list; + if (_function_lambda_definition.return_type is lambda_inferred_type && stl != null && stl.list.Count == 1 && _function_lambda_definition.usedkeyword == 0) + { + 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; + // Надо посмотреть, как это делается для преобразования типов T(x). А пока так + expression_node qq = null; + delegated_methods dm = null; + common_type_node delegate_type = null; + int err_cnt = ErrorsList.Count; + try + { + // Видимо, дело только в лямбде. Попробовать всё обойти и найти захваченные параметры + // Если они есть, то ничего не делать и выйти + + var vis = HasCapturedLambdaParameterInInternalLambdaBody.New(_function_lambda_definition); + vis.ProcessNode(ff.dereferencing_value); + if (vis.HasCapturedParameter) // SSM 28/01/2021 считать это функцией. Будет слабый вывод в редком числе случаев + return; + + qq = convert_strong(ff.dereferencing_value); + if (qq is exit_procedure && stl.list.Count == 1 || qq is local_block_variable_reference && qq.type is compiled_type_node && (qq.type as compiled_type_node).compiled_type == typeof(Action)) + { + // SSM #2172 27/06/20 - тело - это вызов exit + stl.list[0] = new procedure_call(ff, ff.source_context); + _function_lambda_definition.return_type = null; + return; + } + dm = qq.type as delegated_methods; + if (dm == null && qq.type != null && qq.type.IsDelegate) + delegate_type = qq.type as common_type_node; + + } + catch (Exception e) + { + if (ErrorsList.Count != err_cnt)//delete fake errors + ErrorsList.RemoveRange(err_cnt, ErrorsList.Count - err_cnt); + // Погасить все исключения. Значит, не вывелось, и в правой части лямбды - не вызов процедуры, а скорее всего приведение типа T(x) + // К сожалению, сюда попадает случай a->a.Print() где a до более позднего этапа не определяется + // Плохо, но лучше пока не получается + } + if (dm != null && dm.proper_methods != null && dm.proper_methods.Count > 0) + { + if (dm.proper_methods[0].ret_type == null && stl.expr_lambda_body) + { + // Очищаем от Result := + stl.list[0] = new procedure_call(ff, ff.source_context); // заменить result := Print(x) на Print(x) + _function_lambda_definition.return_type = null; + } + } + else if (delegate_type != null) + { + function_node fn = delegate_type.find_in_type("Invoke")[0].sym_info as function_node; + if (fn.return_value_type == null && stl.expr_lambda_body) + { + stl.list[0] = new procedure_call(ff, ff.source_context); + _function_lambda_definition.return_type = null; + } + } + } + } + else + if (!stl.expr_lambda_body) // SSM 26.11.18 + // значит, первый и единственный оператор - не присваивание и это лямбда - процедура! + { + var rns = new LambdaHelper.ResultNodesSearcher(_function_lambda_definition.proc_body); + if (rns.exprList.Count == 0) // Значит, это процедура, т.к. в блоке begin-end нет ни одного result := ... + { + _function_lambda_definition.return_type = null; + } + else _function_lambda_definition.usedkeyword = 1; // значит, это наверняка функция + } + } + else if (_function_lambda_definition.return_type is lambda_inferred_type && stl != null && stl.list.Count > 1 && _function_lambda_definition.usedkeyword == 0) + { + var rns = new LambdaHelper.ResultNodesSearcher(_function_lambda_definition.proc_body); + if (rns.exprList.Count == 0) // Значит, это процедура, т.к. в блоке begin-end нет ни одного result := ... + { + _function_lambda_definition.return_type = null; + } + else _function_lambda_definition.usedkeyword = 1; // значит, это наверняка функция + } + } + + public expression ProcedureForLambdaAndVisit(function_lambda_definition lambdaDefinition, ident_list tempParsList, where_definition_list whereSection) + { + var procDecl = LambdaHelper.ConvertLambdaNodeToProcDefNode(lambdaDefinition); + + if (tempParsList != null) + { + procDecl.proc_header.template_args = tempParsList; + } + + if (whereSection != null && whereSection.defs != null && whereSection.defs.Count != 0) + { + procDecl.proc_header.where_defs = whereSection; + } + + if (!context.func_stack.Empty && context.func_stack.top().polymorphic_state == SemanticTree.polymorphic_state.ps_static + || context.converted_type != null && context.converted_type.IsStatic) + { + procDecl.proc_header.class_keyword = true; + if (procDecl.proc_header.proc_attributes == null) + procDecl.proc_header.proc_attributes = new SyntaxTree.procedure_attributes_list(); + procDecl.proc_header.proc_attributes.proc_attributes.Add(new SyntaxTree.procedure_attribute(PascalABCCompiler.SyntaxTree.proc_attribute.attr_static)); + } + + try + { + visit(procDecl); + } + catch (Exception e) + { + context.remove_lambda_function(procDecl.proc_header.name.meth_name.name, true); + throw; + } + + context.remove_lambda_function(procDecl.proc_header.name.meth_name.name, false); + + return tempParsList == null ? + (expression)procDecl.proc_header.name.meth_name : + (expression)new ident_with_templateparams(procDecl.proc_header.name.meth_name, new template_param_list(tempParsList.idents.Select(l => SyntaxTreeBuilder.BuildSimpleType(l.name)).ToList())); + + } + + int ccc = 0; + public override void visit(SyntaxTree.function_lambda_definition _function_lambda_definition) + { +#if DEBUG + /*if (lambdaProcessingState == LambdaProcessingState.ClosuresProcessingPhase) + { + var s = new string (' ',ccc)+"begin " + _function_lambda_definition.lambda_name + " " + _function_lambda_definition.parameters.expressions[0] + "\n"; + ccc += 2; + System.IO.File.AppendAllText("d:\\bb3.txt", s); + }*/ +#endif + //stl.list[0] = new procedure_call(ff, ff.source_context); - Это надо для превращения функции в процедуру + //_function_lambda_definition.return_type = null; + + + _function_lambda_definition.RealSemTypeOfResExpr = null; // После первого присваивания Result она будет содержать тип type_node в правой части Result + _function_lambda_definition.RealSemTypeOfResult = null; + try + { + stflambda.Push(_function_lambda_definition); + if (_function_lambda_definition.substituting_node != null) + { + if (_function_lambda_definition.substituting_node is dot_node) + { + visit((dot_node)_function_lambda_definition.substituting_node); + } + else if (_function_lambda_definition.substituting_node is ident) + { + visit((ident)_function_lambda_definition.substituting_node); + } + else if (_function_lambda_definition.substituting_node is ident_with_templateparams) + { + visit((ident_with_templateparams)_function_lambda_definition.substituting_node); + } + return; + } + // Внутри makeProcedureForLambdaAndVisit делается procdecl или funcdecl и обходится. + // Поэтому формальный параметр обходится точно!! + //Func makeProcedureForLambdaAndVisit = ProcedureForLambdaAndVisit; + + switch (lambdaProcessingState) + { + case LambdaProcessingState.TypeInferencePhase: + { + MaybeConvertFunctionLambdaDefinitionToProcedureLambdaDefinition(_function_lambda_definition); + if (_function_lambda_definition.lambda_visit_mode == + LambdaVisitMode.VisitForAdvancedMethodCallProcessing) + { + ProcedureForLambdaAndVisit(_function_lambda_definition, null, null); + if (!LambdaHelper.IsAuxiliaryLambdaName(_function_lambda_definition.lambda_name)) + { + LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, _function_lambda_definition); + } + } + + ret.return_value((semantic_node)LambdaHelper.GetTempFunctionNodeForTypeInference(_function_lambda_definition, this)); + + break; + } + case LambdaProcessingState.FinishPhase: + { + if (context.top_function != null && context.top_function.generic_params != null) + { + var pars = context.top_function.generic_params.Select(par => new ident(par.name)).ToList(); + + var whereSection = + CapturedVariablesSubstitutor.GetWhereSection( + generic_parameter_eliminations.make_eliminations_common( + context.top_function.generic_params), pars); + + if (_function_lambda_definition.formal_parameters != null && _function_lambda_definition.formal_parameters.params_list.Count > 0) + { + for (var j = 0; j < _function_lambda_definition.formal_parameters.params_list.Count; j++) + { + if (_function_lambda_definition.formal_parameters.params_list[j].vars_type is lambda_inferred_type) + { + if ((_function_lambda_definition.formal_parameters.params_list[j].vars_type as lambda_inferred_type).real_type is type_node) + { + _function_lambda_definition.formal_parameters.params_list[j].vars_type = + LambdaHelper.ConvertSemanticTypeToSyntaxType((type_node)(_function_lambda_definition.formal_parameters.params_list[j].vars_type as lambda_inferred_type).real_type); + } + } + } + } + + if (_function_lambda_definition.return_type is lambda_inferred_type) + { + if ((_function_lambda_definition.return_type as lambda_inferred_type).real_type is type_node) + { + _function_lambda_definition.return_type = LambdaHelper.ConvertSemanticTypeToSyntaxType((type_node)(_function_lambda_definition.return_type as lambda_inferred_type).real_type); + } + } + + var methodNameToVisit = (ident_with_templateparams)ProcedureForLambdaAndVisit(_function_lambda_definition, new ident_list(pars), whereSection); + _function_lambda_definition.substituting_node = methodNameToVisit; + visit(methodNameToVisit); + } + else + { + var methodNameToVisit = (ident)ProcedureForLambdaAndVisit(_function_lambda_definition, null, null); + _function_lambda_definition.substituting_node = methodNameToVisit; + visit(methodNameToVisit); + } + break; + } + case LambdaProcessingState.ClosuresProcessingPhase: + { +#if DEBUG + //var s = "begin "+_function_lambda_definition.lambda_name + " "+ _function_lambda_definition.parameters.expressions[0] + "\n"; + //System.IO.File.AppendAllText("d:\\bb17.txt", s); +#endif + ProcedureForLambdaAndVisit(_function_lambda_definition, null, null); + LambdaHelper.RemoveLambdaInfoFromCompilationContext(context, _function_lambda_definition); + ret.return_value((semantic_node)LambdaHelper.GetTempFunctionNodeForTypeInference(_function_lambda_definition, this)); + break; + } + case LambdaProcessingState.ClosuresProcessingVisitGeneratedClassesPhase: + { + ProcedureForLambdaAndVisit(_function_lambda_definition, null, null); + break; + } + case LambdaProcessingState.None: + { + if (context.converting_block() == block_type.namespace_block) + { + var methodNameToVisit = (ident)ProcedureForLambdaAndVisit(_function_lambda_definition, null, null); + _function_lambda_definition.substituting_node = methodNameToVisit; + visit(methodNameToVisit); + } + break; + } + } + } + finally + { + stflambda.Pop(); +#if DEBUG + /*if (lambdaProcessingState == LambdaProcessingState.ClosuresProcessingPhase) + { + ccc -= 2; + var s = new string(' ', ccc) + "end " + _function_lambda_definition.lambda_name + " " + _function_lambda_definition.parameters.expressions[0] + "\n"; + System.IO.File.AppendAllText("d:\\bb3.txt", s); + }*/ +#endif + } + } + + public override void visit(SyntaxTree.function_lambda_call _function_lambda_call) + { + SyntaxTree.op_type_node _op_type_node = new SyntaxTree.op_type_node(SyntaxTree.Operators.Assignment); + for (int i = 0; i < _function_lambda_call.parameters.expressions.Count; i++) + { + SyntaxTree.assign _assign = new SyntaxTree.assign(_function_lambda_call.f_lambda_def.parameters.expressions[i] as SyntaxTree.addressed_value, _function_lambda_call.parameters.expressions[i] as SyntaxTree.expression, _op_type_node.type); + ((SyntaxTree.statement_list)_function_lambda_call.f_lambda_def.proc_body).subnodes.Insert(0, _assign); + _assign.source_context = _function_lambda_call.source_context; + } + SyntaxTree.expression_list el = new SyntaxTree.expression_list(); + for (int i = 0; i < _function_lambda_call.f_lambda_def.formal_parameters.params_list.Count; i++) + if (i < _function_lambda_call.parameters.expressions.Count) + el.expressions.Add(_function_lambda_call.parameters.expressions[i]); + else + { + el.expressions.Add(new SyntaxTree.ident(_function_lambda_call.f_lambda_def.formal_parameters.params_list[i].idents.idents[0].name, _function_lambda_call.source_context)); + } + SyntaxTree.method_call _method_call = new SyntaxTree.method_call(el); + _method_call.source_context = _function_lambda_call.source_context; + if (_method_call is SyntaxTree.dereference) + { + ((SyntaxTree.dereference)_method_call).dereferencing_value = (SyntaxTree.addressed_value)(new SyntaxTree.ident(_function_lambda_call.f_lambda_def.lambda_name, _function_lambda_call.source_context)); + } + _method_call.visit(this); + } + + public void lambda_header_visit(SymbolInfo si, SyntaxTree.function_header _function_header, type_node tn1) + { + type_node tn = null; + if (_function_header.return_type == null) + { + if (context.top_function.IsOperator) + AddError(get_location(_function_header), "FUNCTION_NEED_RETURN_TYPE"); + } + if (_function_header.return_type != null) + { + check_parameter_on_complex_type(_function_header.return_type); + if (tn1 != null) + tn = tn1; + else + tn = convert_strong(_function_header.return_type); + //if (tn == SystemLibrary.SystemLibrary.void_type) + // AddError(new VoidNotValid(get_location(_function_header.return_type))); + check_for_type_allowed(tn, get_location(_function_header.return_type)); + } + //(ssyy) moved up, так как при проверке аттрибута override надо знать тип возвращаемого значения + context.top_function.return_value_type = tn; + assign_doc_info(context.top_function, _function_header); + if (_function_header.attributes != null) + { + make_attributes_for_declaration(_function_header, context.top_function); + } + if (context.converted_type != null && has_dll_import_attribute(context.top_function)) + AddError(get_dll_import_attribute(context.top_function).location, "DLLIMPORT_ATTRIBUTE_CANNOT_BE_APPLIED_TO_METHOD"); + if (_function_header.name.class_name != null) + with_class_name = true; + if (_function_header.class_keyword && !has_static_attr(_function_header.proc_attributes.proc_attributes)) + { + SyntaxTree.procedure_attribute pa = new SyntaxTree.procedure_attribute(PascalABCCompiler.SyntaxTree.proc_attribute.attr_static); + pa.source_context = _function_header.source_context; + _function_header.proc_attributes.proc_attributes.Add(pa); + } + weak_node_test_and_visit(_function_header.proc_attributes); + if (context.top_function.IsOperator) + { + common_method_node cmmn = context.top_function as common_method_node; + //if (cmmn == null) + //{ + // throw new OverloadOperatorMustBeStaticFunction(get_location(_function_header), context.top_function); + //} + if (cmmn != null && cmmn.polymorphic_state != SemanticTree.polymorphic_state.ps_static) + { + AddError(get_location(_function_header), "OVERLOADED_OPERATOR_MUST_BE_STATIC_FUNCTION"); + } + if (cmmn != null && (cmmn.name == compiler_string_consts.implicit_operator_name || cmmn.name == compiler_string_consts.explicit_operator_name)) + if (!convertion_data_and_alghoritms.eq_type_nodes(tn, cmmn.comperehensive_type as type_node) && !convertion_data_and_alghoritms.eq_type_nodes(cmmn.comperehensive_type as type_node, cmmn.parameters[0].type)) + { + AddError(get_location(_function_header.return_type), "RETURN_VALUE_SHOULD_HAVE_TYPE_{0}", (cmmn.comperehensive_type as type_node).PrintableName); + } + else if (convertion_data_and_alghoritms.eq_type_nodes(tn, cmmn.parameters[0].type)) + { + AddError(get_location(_function_header), "CIRCURAL_TYPE_CONVERSION_DEFINITION"); + } + } + with_class_name = false; + if (context.top_function != null && context.top_function is common_namespace_function_node && (context.top_function as common_namespace_function_node).ConnectedToType != null && !context.top_function.IsOperator) + { + concrete_parameter_type cpt = concrete_parameter_type.cpt_none; + SemanticTree.parameter_type pt = PascalABCCompiler.SemanticTree.parameter_type.value; + if ((context.top_function as common_namespace_function_node).ConnectedToType.is_value_type) + { + cpt = concrete_parameter_type.cpt_var; + pt = PascalABCCompiler.SemanticTree.parameter_type.var; + } + common_parameter cp = new common_parameter(compiler_string_consts.self_word, (context.top_function as common_namespace_function_node).ConnectedToType, pt, + context.top_function, cpt, null, null); + context.top_function.parameters.AddElementFirst(cp); + context.top_function.scope.AddSymbol(compiler_string_consts.self_word, new SymbolInfo(cp)); + } + CheckOverrideOrReintroduceExpectedWarning(get_location(_function_header)); + + bool unique = context.close_function_params(body_exists); + if (context.top_function.return_value_type == null) + AddError(get_location(_function_header), "FUNCTION_NEED_RETURN_TYPE"); + if (_function_header.where_defs != null) + { + if (unique) + { + visit_where_list(_function_header.where_defs); + } + else + { + AddError(get_location(_function_header.where_defs), "WHERE_SECTION_MUST_BE_ONLY_IN_FIRST_DECLARATION"); + } + } + convertion_data_and_alghoritms.create_function_return_variable(context.top_function, si); + + /*if (_function_header.name != null && context.converted_compiled_type != null && context.top_function is common_namespace_function_node) + { + if (context.FindMethodToOverride(context.top_function as common_namespace_function_node) != null) + AddError(new CanNotDeclareExtensionMethodAsOverrided(get_location(_function_header))); + }*/ + //TODO: Разобрать подробнее. + if (!body_exists) + { + if ((context.top_function.semantic_node_type == semantic_node_type.common_method_node) + || ((context.func_stack_size_is_one()) && (_is_interface_part))) + { + context.leave_block(); + } + } + body_exists = false; + } + + + public override void visit(SyntaxTree.lambda_inferred_type lit) //lroman// + { + return_value(lit.real_type as type_node); + } + + public override void visit(SyntaxTree.semantic_check sem) + { + if (sem == null) + return; + switch (sem.CheckName) + { + case "ExprIsInteger": + var ex = (SyntaxTree.expression)sem.param[0]; + expression_node en = convert_strong(ex); + en.location = get_location(ex); + if (en.type != SystemLibrary.SystemLibrary.integer_type) + AddError(get_location(ex), "STRING_CONSTANT_OR_IDENTIFIER_EXPECTED"); + break; + case " ": + break; + case " ": + break; + } + } + + public override void visit(SyntaxTree.same_type_node st) // SSM 22/06/13 + { + expression_node en = convert_strong(st.ex); + if (en == null) + AddError(get_location(st.ex),"CANNOT_EVALUATE_FUNCTION_TYPE"); + return_value(en.type); + } + + public type_node try_calc_expr_type(SyntaxTree.expression ex) // SSM 10.07.13 + { + try + { + expression_node en = convert_strong(ex); + return en.type; + } + catch (Exception e) + { + return new undefined_type("#UndefType", null); + } + } + + public override void visit(SyntaxTree.semantic_type_node stn) + { + return_value(stn.type as type_node); + } + + // SSM 10.01.16 впервые для реализации Tuple - t[0] + public override void visit(SyntaxTree.semantic_addr_value sav) + { + return_value(sav.expr as expression_node); + } + + public bool SameTypeAutoClasses(List names, List types, common_type_node t) + { + if (t.properties.Count() != names.Count()) + return false; + + var tnames = t.properties.Select(tt => tt.name); + + return types.SequenceEqual(t.fields.Select(tt => tt.type)) && names.SequenceEqual(tnames, StringComparer.OrdinalIgnoreCase); + //return true; + } + + public override void visit(SyntaxTree.unnamed_type_object unn) // SSM 27.06.13 + { + var l = unn.ne_list; + var names = l.name_expr.Select(x=>x.name).ToList(); + var strnames = names.Select(id=>id.name).ToList(); // преобразование idents в строки + + /*var tt1 = l.name_expr[0].expr; + var tse = convert_strong(tt1);*/ + + var semantic_exprs = l.name_expr.Select(x => convert_strong(x.expr)).ToList(); + for (var i = 0; i < semantic_exprs.Count; i++) + { + var ex = semantic_exprs[i]; + try_convert_typed_expression_to_function_call(ref ex); + semantic_exprs[i] = ex; + } + + var semantic_types = semantic_exprs.Select(x => x.type).ToList(); + var types = semantic_types.Select(x => SyntaxTreeBuilder.BuildSemanticType(x)).ToList(); + + contextChanger.SaveContextAndUpToGlobalLevel(); + + var tt = context._cmn.types.Where(t => t.name.StartsWith("AnonymousType#")); // найти все анонимные типы, полученные в текущей компиляции + + var typ = tt.FirstOrDefault(t => SameTypeAutoClasses(strnames, semantic_types, t)); // найти структурно совпадающий уже существующий анонимный тип + + // Генерация глобальных описаний - перенесена с синтаксического уровня + if (typ != null) + unn.set_name(typ.name); // если нашли, то просто меняем имя на имя этого класса + else + { + var td = SyntaxTreeBuilder.BuildAutoClass(unn.name(), names, types, unn.is_class); + visit(td); + } + + contextChanger.RestoreCurrentContext(); + + // Сахарный узел. Переадресация дальнейшей генерации узлу new_ex + visit(unn.new_ex); + } + + public override void visit(SyntaxTree.short_func_definition def) // SSM 20.07.13 + { + // Сахарный узел. Переадресация дальнейшей генерации узлу procedure_definition + visit(def.procdef); + } + + public override void visit(matching_expression _matching_expression) + { + throw new NotSupportedError(get_location(_matching_expression)); + } + + public override void visit(SyntaxTree.sequence_type _sequence_type) // сахарный узел + { + var pt = _sequence_type.elements_type.DescendantNodes(TraversalType.PostOrder,null,true).FirstOrDefault(s => s is procedure_header); + if (pt != null) + { + AddError(get_location(pt), "PROCEDURE_TYPE_SHOULD_BE_REPLACED_BY_TYPE_NAME_IN_THIS_CONTEXT"); + } + // SSM 11/05/15 sugared node + var l = new List(); + l.Add(new ident("?System")); + l.Add(new ident("Collections")); + l.Add(new ident("Generic")); + l.Add(new ident("IEnumerable")); + var tr = new template_type_reference(new named_type_reference(l), + new template_param_list(_sequence_type.elements_type, _sequence_type.elements_type.source_context), + _sequence_type.source_context); + visit(tr); + } + + public override void visit(SyntaxTree.modern_proc_type _modern_proc_type) // сахарный узел + { + if (_modern_proc_type.res != null) + { + var l = new List(); + l.Add(new ident("?System")); + l.Add(new ident("Func")); + var t = new template_param_list(); + if (_modern_proc_type.aloneparam != null) + t.Add(_modern_proc_type.aloneparam); + if (_modern_proc_type.el != null) + { + var en = _modern_proc_type.el; + if (en.enumerators.Count == 1) + AddError(get_location(en.enumerators[0].name), "ONE_TYPE_PARAMETER_MUSTBE_WITHOUT_PARENTHESES"); + for (int i = 0; i < en.enumerators.Count; i++) + { + if (en.enumerators[i].value != null) + AddError(get_location(en.enumerators[i].name), "ONE_TKIDENTIFIER"); + + if (!(en.enumerators[i].name is named_type_reference)) + AddError(get_location(en.enumerators[i].name), "ONE_TKIDENTIFIER"); + + t.Add(en.enumerators[i].name); // ??????????????? + } + } + t.Add(_modern_proc_type.res, _modern_proc_type.res.source_context); + t.source_context = _modern_proc_type.source_context; + var ttr = new template_type_reference(new named_type_reference(l), t, _modern_proc_type.source_context); + visit(ttr); + } + else if (_modern_proc_type.aloneparam != null || _modern_proc_type.el != null) + { + var l = new List(); + l.Add(new ident("?System")); + l.Add(new ident("Action")); + var t = new template_param_list(); + if (_modern_proc_type.aloneparam != null) + t.Add(_modern_proc_type.aloneparam); + if (_modern_proc_type.el != null) + { + var en = _modern_proc_type.el; + if (en.enumerators.Count == 1) + AddError(get_location(en.enumerators[0].name), "ONE_TYPE_PARAMETER_MUSTBE_WITHOUT_PARENTHESES"); + for (int i = 0; i < en.enumerators.Count; i++) + { + + if (en.enumerators[i].value != null) + AddError(get_location(en.enumerators[i].name), "ONE_TKIDENTIFIER"); + + if (!(en.enumerators[i].name is named_type_reference)) + AddError(get_location(en.enumerators[i].name), "ONE_TKIDENTIFIER"); + + t.Add(en.enumerators[i].name); + } + } + t.source_context = _modern_proc_type.source_context; + var ttr = new template_type_reference(new named_type_reference(l), t, _modern_proc_type.source_context); + visit(ttr); + } + else + { + var l = new List(); + l.Add(new ident("?System")); + l.Add(new ident("Action")); + var ntr = new named_type_reference(l); + visit(ntr); + } + } + + // Это в куче мест надо. Потому что либо compiled_type_node, либо compiled_generic_instance_type_node + // compiled_type_node если в записи A все типы NETовские + // compiled_generic_instance_type_node если в записи A хоть один тип - паскалевский + public Type ConvertSemanticTypeNodeToNETType(type_node tn) + { + if (tn is compiled_generic_instance_type_node) + { + var tnc = (tn as compiled_generic_instance_type_node); + var itnc = tnc.original_generic as compiled_type_node; + var tt = itnc.compiled_type; + if (tt.IsGenericType) + tt = tt.GetGenericTypeDefinition(); + return tt; + } + else if (tn is compiled_type_node) + { + var itnc = (tn as compiled_type_node); + var tt = itnc.compiled_type; + if (tt.IsGenericType) + tt = tt.GetGenericTypeDefinition(); + return tt; + } + return null; + } + + /*expression_list construct_expression_list_for_slice_expr(SyntaxTree.slice_expr sl) + { + // situation = 0 - ничего не пропущено + // situation = 1 - пропущен from + // situation = 2 - пропущен to + // situation = 3 - пропущены from и to + // Пропущенность кодируется тем, что в соответствующем поле - int.MaxValue + // step может просто отсутствовать - это параметр по умолчанию в SystemSlice + + int situation = 0; + + if ((sl.from is int32_const) && (sl.from as int32_const).val == int.MaxValue) + situation += 1; + if ((sl.to is int32_const) && (sl.to as int32_const).val == int.MaxValue) + situation += 2; + + var el = new SyntaxTree.expression_list(); + el.Add(new int32_const(situation)); + el.Add(sl.from); // Это плохо - считается 2 раза. Надо делать semantic_expr_node !!!? Нет!!! + // Если там будет лямбда, то не будет работать - известно, что semantic_expr_node не работает с лямбдами + // т.к. они несколько раз обходят код. + el.Add(sl.to); + if (sl.step != null) + el.Add(sl.step); + + return el; + }*/ + + // frninja 04/03/16 - для yield + + // frninja 06/06/16 - фикс для видимости private методов и полей с классов в том же модуле + private unit_node GetUnknownIdentUnit(definition_node dn) + { + if (dn is class_field) + { + return ((dn as class_field).cont_type.comprehensive_namespace != null) + ? (dn as class_field).cont_type.comprehensive_namespace.cont_unit + : null; + } + else if (dn is common_method_node) + { + return ((dn as common_method_node).cont_type.comprehensive_namespace != null) + ? (dn as common_method_node).cont_type.comprehensive_namespace.cont_unit + : null; + } + else if (dn is common_property_node) + { + return ((dn as common_property_node).common_comprehensive_type.comprehensive_namespace != null) + ? (dn as common_property_node).common_comprehensive_type.comprehensive_namespace.cont_unit + : null; + } + + return null; + } + // end frninja 06/06/16 + + private bool CheckIsStaticName(definition_node dn) + { + if (dn is class_field && (dn as class_field).polymorphic_state == SemanticTree.polymorphic_state.ps_static) + return true; + + if (dn is common_method_node && (dn as common_method_node).polymorphic_state == SemanticTree.polymorphic_state.ps_static) + return true; + + if (dn is common_property_node && (dn as common_property_node).polymorphic_state == SemanticTree.polymorphic_state.ps_static) + return true; + + if (dn is compiled_function_node && (dn as compiled_function_node).polymorphic_state == SemanticTree.polymorphic_state.ps_static) + return true; + + if (dn is compiled_property_node && (dn as compiled_property_node).polymorphic_state == SemanticTree.polymorphic_state.ps_static) + return true; + + return false; + } + + private bool CheckUnknownIdentNeedsClassCapture(SyntaxTree.yield_unknown_ident _unk, out bool isStaticIdent) + { + + string Consts__Self = YieldHelpers.YieldConsts.Self; + + // Find semantic class containing iterator (yield-method) with unknown ident + var iteratorContainingClass = context._ctn.fields.Where(f => f.name == Consts__Self).FirstOrDefault()?.type; + //var iteratorContainingClass = context._cmn.types.Where(t => t.name == _unk.ClassName.name).First(); + + isStaticIdent = false; + + if (iteratorContainingClass != null) + { + // Search for unknown ident in class + var found = iteratorContainingClass.find(_unk.UnknownID.name); + if (found != null) + { + // class_field - поле класса + // common_method_node - метод класса + // common_property_node - свойство класса + + // че там с .NET как базовым? + // compiled_function_node - метод базового .NET класса + // compiled_property_node - свойство базового .NET класса + + // че с классом из другого модуля? + // то же что и с классом из этого же + var found_unit = found.FirstOrDefault(); + isStaticIdent = CheckIsStaticName(found_unit.sym_info); + + if (found_unit.sym_info is class_field + || found_unit.sym_info is class_constant_definition // SSM #2152 + || found_unit.sym_info is common_method_node + || found_unit.sym_info is common_property_node + || found_unit.sym_info is compiled_function_node + || found_unit.sym_info is compiled_property_node) + { + if (!isStaticIdent && _unk.IsYieldInStaticMethod) + return false; + + // frninja 06/06/16 - фиксим private того же модуля + if ((iteratorContainingClass is common_type_node) + && this.GetUnknownIdentUnit(found_unit.sym_info) == + (((iteratorContainingClass as common_type_node).comprehensive_namespace != null) + ? (iteratorContainingClass as common_type_node).comprehensive_namespace.cont_unit + : null)) + { + return true; + } + else if (found_unit.access_level != access_level.al_private) + { + return true; + } + } + + // common_namespace_function_node - глобальный метод + + } + } + + return false; + } + + private dot_node CaptureUnknownIdent(yield_unknown_ident unk, bool isStaticIdent = false) + { + if (isStaticIdent) + { + return new dot_node(unk.ClassName, unk.UnknownID); + } + string Consts__Self = YieldHelpers.YieldConsts.Self; + + return new dot_node(new dot_node(new ident("self"), new ident(Consts__Self)), unk.UnknownID); + } + + private SyntaxTree.addressed_value_funcname ProcessUnknownIdent(yield_unknown_ident unk) + { + bool isStaticIdent; + if (CheckUnknownIdentNeedsClassCapture(unk, out isStaticIdent)) + { + var uid = CaptureUnknownIdent(unk, isStaticIdent); + return uid; + } + else + { + return unk.UnknownID; + } + } + + public override void visit(SyntaxTree.yield_node yn) + { + // надо что то сгенерировать, иначе выдается ложное предупреждение о недостижимом коде и проч. + /*var ass = new assign("Result", new nil_const()); + visit(ass); + var pc = new procedure_call("exit"); + visit(pc);*/ + } + + // frninja - захват полей класса для yield + public override void visit(SyntaxTree.yield_unknown_ident _unk) + { + ProcessUnknownIdent(_unk).visit(this); + } + + public override void visit(SyntaxTree.yield_unknown_expression_type _unk_expr) + { + // Отвечает за типизацию всех переменных с автовыведением типа + // Пробую сделать по-другому: перевести в auto_type и потом на присваивании перехватить + var t = new semantic_type_node(new auto_type(get_location(_unk_expr))); + t.visit(this); + } + + // frninja 29/05/16 - выявляем тип перемнной в foreach + public override void visit(SyntaxTree.yield_unknown_foreach_type _unk) + { + var t = new semantic_type_node(new ienumerable_auto_type(get_location(_unk))); + t.visit(this); + } + + public override void visit(SyntaxTree.dot_question_node dqn) + { + // a?.b + AddError(get_location(dqn), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", dqn.GetType().Name); + //var q = ConvertToQCE(dqn); + //visit(q); + } + + public override void visit(SyntaxTree.semantic_check_sugared_statement_node st) + { + /*if (st.visited) + return; + st.visited = true;*/ + if (st.typ as System.Type == typeof(SyntaxTree.assign_tuple)) + { + var vars = st.lst[0] as SyntaxTree.addressed_value_list; + var expr = st.lst[1] as SyntaxTree.expression; + semantic_check_assign_tuple(vars, expr); + } + else if (st.typ as System.Type == typeof(SyntaxTree.assign_var_tuple)) + { + var idents = st.lst[0] as SyntaxTree.ident_list; + var expr = st.lst[1] as SyntaxTree.expression; + semantic_check_assign_var_tuple(idents, expr); + } + else if (st.typ as System.Type == typeof(SyntaxTree.loop_stmt)) + { + var expr = st.lst[0] as SyntaxTree.expression; + semantic_check_loop_stmt(expr); + } + else if (st.typ as System.Type == typeof(SyntaxTree.foreach_stmt) && st.lst.Count == 3) // для NewRange Visitorа. Если будет перекрытие, то надоделать новые типы-маркеры + { + var expr = st.lst[0] as SyntaxTree.diapason_expr_new; + var td = st.lst[1] as SyntaxTree.type_definition; + var id = st.lst[2] as SyntaxTree.ident; + semantic_check_for_new_range(expr, td, id); + } + /*else if (st.typ as System.Type == typeof(SyntaxTree.foreach_stmt) && st.lst.Count == 1) // для a.Indices. Пока непонятно, где описывать тип-маркер + { + var expr = st.lst[0] as SyntaxTree.expression; + semantic_check_for_indices(expr); + }*/ + // Patterns + else if (st.typ is SemanticCheckType.MatchedExpression) // Это безобразие - SemanticCheckType в TreeHelper.cs помещать!!! + { + var expr = st.lst[0] as expression; + CheckMatchedExpression(expr); + } + else if (st.typ is SemanticCheckType.MatchedExpressionAndType) + { + var expr = st.lst[0] as expression; + var type = st.lst[1] as type_definition; + CheckIfCanBeMatched(expr, type); + } + else if (st.typ is SemanticCheckType.MatchedExpressionAndExpression) + { + var matchedExpr = st.lst[0] as expression; + var patternExpr = st.lst[1] as expression; + CheckIfCanBeMatched(matchedExpr, patternExpr); + } + else if (st.typ is SemanticCheckType.MatchedTuple) + { + var tuple = st.lst[0] as expression; + var length = st.lst[1] as int32_const; + CheckIfCanBeMatched(tuple, length); + } + // !Patterns + // Slices + else if (st.typ is SemanticCheckType.SliceAssignmentTypeCompatibility) + { + var to = st.lst[0] as expression; + var from = st.lst[1] as expression; + var mc = st.lst[2] as method_call; + semantic_check_slice_assignment_types(to, from, mc); + } + // !Slices + else + { + AddError(get_location(st), "MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}", (st.typ as System.Type)?.Name ?? "Unknown"); + } + ret.reset(); // обязательно очистить - этот узел в семантику ничего не должен приносить! + ReplaceUsingParent(st, new PascalABCCompiler.SyntaxTree.empty_statement()); + } + + public override void visit(SyntaxTree.semantic_check_sugared_var_def_statement_node st) + { + if (st.typ as System.Type == typeof(SyntaxTree.assign_var_tuple)) + { + var idents = st.lst[0] as SyntaxTree.ident_list; + var expr = st.lst[1] as SyntaxTree.expression; + semantic_check_assign_var_tuple(idents, expr); + } + else + { + AddError(get_location(st), "MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}", (st.typ as System.Type)?.Name ?? "Unknown"); + } + ret.reset(); // обязательно очистить - этот узел в семантику ничего не должен приносить! + } + + public override void visit(SyntaxTree.sugared_expression ex) + { + /*if (ex.sugared_expr is SyntaxTree.tuple_node) + { + semantic_check_tuple(ex.sugared_expr as SyntaxTree.tuple_node); + } + else*/ + { + AddError(get_location(ex), "MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}", ex.sugared_expr.GetType().Name); + } + + ProcessNode(ex.new_expr); // обойти десахарное выражение - обязательно ProcessNode - visit нельзя! + } + + public method_call ToNullable(expression e) + { + var dn = new dot_node(new ident("PABCSystem"), new ident("DQNToNullable")); + return new method_call(dn, new expression_list(e), e.source_context); + } + + public override void visit(SyntaxTree.sugared_addressed_value av) + { + if (av.sugared_expr is SyntaxTree.diapason_expr_new) + { + semantic_check_method_call_as_diapason_expr(av.new_addr_value as SyntaxTree.method_call); + } + else if (av.sugared_expr is SyntaxTree.slice_expr) // и slice_expr_question + { + semantic_check_method_call_as_slice_expr(av.new_addr_value as SyntaxTree.method_call); + } + else if (av.sugared_expr is SyntaxTree.dot_question_node) + { + var qce = av.new_addr_value as SyntaxTree.question_colon_expression; + var av_cs = convert_strong(qce.ret_if_false); + try_convert_typed_expression_to_function_call(ref av_cs); + if (!type_table.is_with_nil_allowed(av_cs.type)) + { + var dn = new dot_node(new ident("PABCSystem"), new ident("DQNToNullable")); + (av.new_addr_value as SyntaxTree.question_colon_expression).ret_if_false + = new method_call(dn, new expression_list((av.new_addr_value as SyntaxTree.question_colon_expression).ret_if_false), av.source_context); + + /*var avqce = av.new_addr_value as SyntaxTree.question_colon_expression; + //var dn = new dot_node(new ident("PABCSystem"), new ident("DQNToNullable")); + avqce.ret_if_false = ToNullable(avqce.ret_if_false); + //new method_call(dn, new expression_list(avqce.ret_if_false), av.source_context);*/ + } + semantic_check_dot_question(av.new_addr_value as SyntaxTree.question_colon_expression); + } + else if (av.sugared_expr is SyntaxTree.bin_expr) // Это пришло от i in (2..5). Плохо, что могут быть другие bin_expr + { + semantic_check_method_call_as_inrange_expr(av.new_addr_value as SyntaxTree.method_call); + } + else + { + AddError(get_location(av), "MISSED_SEMANTIC_CHECK_FOR_SUGARED_NODE_{0}", av.sugared_expr.GetType().Name); + } + + ProcessNode(av.new_addr_value); // обойти десахарное + } + + private void CheckUnpacking(expression ex, out expression_node sem_ex, out bool IsTuple, out bool IsSequence, int countvars, syntax_tree_node stn) + { + sem_ex = convert_strong(ex); + sem_ex = convert_if_typed_expression_to_function_call(sem_ex); + var t = ConvertSemanticTypeNodeToNETType(sem_ex.type); + if (t == null) + AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); + IsTuple = false; + IsSequence = false; + if (t.FullName.StartsWith("System.Tuple")) + IsTuple = true; + if (!IsTuple) + { + if (t.Name.Equals("IEnumerable`1") || t.GetInterface("IEnumerable`1") != null) + IsSequence = true; + } + if (!IsTuple && !IsSequence) + { + AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); + } + if (IsTuple) + { + if (countvars > t.GetGenericArguments().Count()) + AddError(get_location(stn), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT"); + } + } + + private addressed_value UnpackingExpr(int i, bool IsTuple, bool IsSequence, string tname) + { + addressed_value dn = null; + if (IsTuple) + dn = new dot_node(new ident(tname), new ident("Item" + (i + 1).ToString())); + else if (IsSequence) + { + dn = new dot_node(new ident(tname), new ident("ElementAt")); + var pars = new SyntaxTree.expression_list(new int32_const(i)); + + dn = new method_call(dn, pars); + } + return dn; + } + + public override void visit(SyntaxTree.assign_tuple asstup) // сахарный узел + { + AddError(get_location(asstup), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", asstup.GetType().Name); + // На семантике тяжело делать сахар с определениями переменных, которые потом захватываются лямбдами: var (m,n) := t; ArrGen(x->x+m); + // Перенесено на синтаксис с генерацией узла semantic_ith_element_of, разворачивающегося на семантике + + /*CheckUnpacking(asstup.expr, out var sem_ex, out var IsTuple, out var IsSequence, asstup.vars.variables.Count(), asstup.vars); + var sem_node = new SyntaxTree.semantic_addr_value(sem_ex); // чтобы два раза не делать convert_strong + + //semantic_check_assign_tuple(asstup.vars, asstup.expr); + + var tname = "#temp_var" + UniqueNumStr(); + + var tt = new var_statement(new ident(tname), sem_node; // тут semantic_addr_value хранит на самом деле expr - просто неудачное название + var st = new statement_list(); + st.Add(tt); + + var n = asstup.vars.variables.Count(); + for (var i = 0; i < n; i++) + { + var a = new assign(asstup.vars.variables[i], + //new dot_node(new ident(tname), new ident("Item" + (i + 1).ToString())), + UnpackingExpr(i, IsTuple, IsSequence, tname), + Operators.Assignment, + asstup.vars.variables[i].source_context); + st.Add(a); + } + visit(st);*/ + } + + public override void visit(SyntaxTree.assign_var_tuple assvartup) // сахарный узел + { + AddError(get_location(assvartup), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", assvartup.GetType().Name); + // На семантике тяжело делать сахар с определениями переменных, которые потом захватываются лямбдами: var (m,n) := t; ArrGen(x->x+m); + + //CheckUnpacking(assvartup.expr, out var sem_ex, out var IsTuple, out var IsSequence, assvartup.idents.idents.Count(), assvartup.idents); + + /*var sem_ex = convert_strong(assvartup.expr); + sem_ex = convert_if_typed_expression_to_function_call(sem_ex); + var t = ConvertSemanticTypeNodeToNETType(sem_ex.type); + if (t == null) + AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); + + var IsTuple = false; + var IsSequence = false; + if (t.FullName.StartsWith("System.Tuple")) + IsTuple = true; + if (!IsTuple) + { + if (t.Name.Equals("IEnumerable`1") || t.GetInterface("IEnumerable`1") != null) + IsSequence = true; + } + if (!IsTuple && !IsSequence) + { + AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); + } + + if (IsTuple) + { + var nn = assvartup.idents.idents.Count(); + if (nn > t.GetGenericArguments().Count()) + AddError(get_location(assvartup.idents), "TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMRNT"); + }*/ + + + // В зависимости от типа выражения по-разному распаковывать + // Распаковывать можно только для кортежей или последовательностей + // if IsTuple ... + // if IsSequence ... + // else AddError(либо кортеж либо последовательность) + + /*var sem_node = new SyntaxTree.semantic_addr_value(sem_ex); // чтобы два раза не делать convert_strong + + //semantic_check_assign_var_tuple(assvartup.idents, sem_node); + + var tname = "#temp_var" + UniqueNumStr(); + + var tt = new var_statement(new ident(tname), sem_node); + + var sl = new statement_list(); + sl.Add(new SyntaxTree.empty_statement()); + sl.Add(tt); + + var n = assvartup.idents.idents.Count(); + for (var i = 0; i < n; i++) + { + var rr = assvartup.idents.idents[i] as ident; + var a = new var_statement(rr, + //new dot_node(new ident(tname),new ident("Item" + (i + 1).ToString())), + //dn, + UnpackingExpr(i, IsTuple, IsSequence, tname), + assvartup.idents.idents[i].source_context + ); + sl.Add(a); + } + //assvartup.sl = sl; + ReplaceStatementUsingParent(assvartup, sl.list); // добавляем пустой оператор чтобы здесь его пропустить, а обходить следующие + //sl.IsInternal = true; + //ReplaceUsingParent(assvartup, sl); // меняем один оператор на один. На 2 и 3 проходе лямбды обходится именно он + //visit_statement_list_internal(sl);*/ + } + + public override void visit(semantic_ith_element_of ith) + { + var sem_ex = convert_strong(ith.id); + sem_ex = convert_if_typed_expression_to_function_call(sem_ex); + var t = ConvertSemanticTypeNodeToNETType(sem_ex.type); + if (t == null) + AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); + var IsTuple = false; + var IsSequence = false; + if (t.FullName.StartsWith("System.Tuple")) + IsTuple = true; + if (!IsTuple) + { + if (t.Name.Equals("IEnumerable`1") || t.GetInterface("IEnumerable`1") != null) + IsSequence = true; + } + if (!IsTuple && !IsSequence) + { + AddError(sem_ex.location, "TUPLE_OR_SEQUENCE_EXPECTED"); + } + + //addressed_value dn = null; + var i = (ith.index as int32_const).val; + if (IsTuple) + { + var dn = new dot_node(ith.id.TypedClone(), new ident("Item" + (i + 1).ToString())); + ReplaceUsingParent(ith, dn); + visit(dn); + } + else if (IsSequence) + { + var dn = new dot_node(ith.id.TypedClone(), new ident("ElementAt")); + var pars = new SyntaxTree.expression_list(new int32_const(i)); + var mc = new method_call(dn, pars); + ReplaceUsingParent(ith, mc); + visit(mc); + } + } + + + public override void visit(var_tuple_def_statement vtd) + { + AddError(get_location(vtd), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", vtd.GetType().Name); + // На семантике тяжело делать сахар с определениями переменных, которые потом захватываются лямбдами: var (m,n) := t; ArrGen(x->x+m); + + // Состоит из var_def_statements. Некоторые являются var_tuple_def_statement + // Их надо найти и сделать несколько секций variable_definitions - без семантических проверок. + // Каждую var_tuple_def_statement надо заменить на assign_var_tuple - одну на секцию variable_definitions + // А потом оставшаяся часть визитора сделает семантические проверки + + /*CheckUnpacking(vtd.inital_value, out var sem_ex, out var IsTuple, out var IsSequence, vtd.vars.idents.Count(), vtd.vars); + var sem_node = new SyntaxTree.semantic_addr_value(sem_ex); // чтобы два раза не делать convert_strong + + //semantic_check_assign_var_tuple(vtd.vars, vtd.inital_value); + + var tname = "#temp_var" + UniqueNumStr(); + //var vd = new List(); + //vd.Add(new semantic_check_sugared_var_def_statement_node(typeof(assign_var_tuple), new List { vtd.vars, vtd.inital_value }, vtd.source_context)); // Это нужно для проверок на этапе преобразования в семантику + //visit(vd[0]); + + var tt1 = new var_def_statement(new ident(tname), vtd.inital_value); + ProcessNode(tt1); + var nn = vtd.vars.idents.Count(); + for (var i = 0; i < nn; i++) + { + var a = new var_def_statement(vtd.vars.idents[i], + UnpackingExpr(i, IsTuple, IsSequence, tname), + //new dot_node(new ident(tname), new ident("Item" + (i + 1).ToString())), + vtd.vars.idents[i].source_context); + ProcessNode(a); + }*/ + } + + public void ReplaceVarTupleDefStatementUsingParent(var_tuple_def_statement from, IEnumerable to) + { + foreach (var x in to) + x.Parent = from.Parent; + var sl = from.Parent as variable_definitions; + if (sl != null) + { + sl.ReplaceInList(from, to); + } + } + + + + public override void visit(SyntaxTree.slice_expr sl) // сахарный узел + { + AddError(get_location(sl), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", sl.GetType().Name); + + /* + // Преобразуется в вызов a.SystemSlice(situation,from,to,step) + // Тип a должен быть array of T, List или string + semcheck(sl); + + // Действия уровня синтаксиса. Можно вынести на синтаксический уровень как desugaring для сахарного узла + var el = construct_expression_list_for_slice_expr(sl); + var mc = new method_call(new dot_node(sl.v, new ident("SystemSlice", sl.v.source_context), sl.v.source_context), el, sl.source_context); + + visit(mc);*/ + } + + public override void visit(SyntaxTree.slice_expr_question sl) // сахарный узел + { + AddError(get_location(sl), "SUGARED_NODE_{0}_IN_SYNTAX_TREE_VISITOR", sl.GetType().Name); + /* + // Преобразуется в вызов a.SystemSlice(situation,from,to,step) + // Тип a должен быть array of T, List или string + semcheck(sl); + + var el = construct_expression_list_for_slice_expr(sl); + var mc = new method_call(new dot_node(sl.v, new ident("SystemSliceQuestion", sl.v.source_context), sl.v.source_context), el, sl.source_context); + + visit(mc);*/ + } + } } \ No newline at end of file diff --git a/bin/Lng/Eng/SyntaxTreeVisitorsErrors.dat b/bin/Lng/Eng/SyntaxTreeVisitorsErrors.dat index 053e69c11..08bc05912 100644 --- a/bin/Lng/Eng/SyntaxTreeVisitorsErrors.dat +++ b/bin/Lng/Eng/SyntaxTreeVisitorsErrors.dat @@ -36,4 +36,5 @@ NESTED_RECORD_CAN_CONTAIN_ONLY_ONE_PUBLIC_VISIBILITY_SECTION=Nested records can NESTED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS=Nested records can not contain several visibility section UNNAMED_RECORD_CANNOT_CATCH_NAMES_FROM_NONGLOBAL_CONTEXT=Nested records cannot catch names from nonglobal context TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMENT=Too many elements on the left side of tuple assignment -NESTED_LAMBDAS_MAXIMUM_10=Maximum number of nested lambdas = 10 \ No newline at end of file +NESTED_LAMBDAS_MAXIMUM_10=Maximum number of nested lambdas = 10 +EMBEDDED_STATEMENT_CANNOT_BE_A_DECLARATION=Embedded statement cannot be a declaration or labeled statement \ No newline at end of file diff --git a/bin/Lng/Rus/SyntaxTreeVisitorsErrors.dat b/bin/Lng/Rus/SyntaxTreeVisitorsErrors.dat index f7faeefe7..cdab37d66 100644 --- a/bin/Lng/Rus/SyntaxTreeVisitorsErrors.dat +++ b/bin/Lng/Rus/SyntaxTreeVisitorsErrors.dat @@ -40,4 +40,5 @@ NESTED_RECORD_CAN_CONTAIN_ONLY_ONE_PUBLIC_VISIBILITY_SECTION=Вложенные NESTED_RECORD_CANNOT_CONTAIN_SEVERAL_VISIBILITY_SECTIONS=Вложенные записи не могут содержать несколько секций видимости NESTED_RECORD_CANNOT_CATCH_NAMES_FROM_NONGLOBAL_CONTEXT=Вложенные записи не могут захватывать имена из неглобального контекста TOO_MANY_ELEMENTS_ON_LEFT_SIDE_OF_TUPLE_ASSIGNMENT=Слишком много элементов в левой части при присваивании кортежа -NESTED_LAMBDAS_MAXIMUM_10=Максимальный уровень вложенности лямбд равен 10 \ No newline at end of file +NESTED_LAMBDAS_MAXIMUM_10=Максимальный уровень вложенности лямбд равен 10 +EMBEDDED_STATEMENT_CANNOT_BE_A_DECLARATION=Вложенная инструкция не может быть объявлением, используйте операторные скобки \ No newline at end of file diff --git a/bin/Lng/Ukr/SyntaxTreeVisitorsErrors.dat b/bin/Lng/Ukr/SyntaxTreeVisitorsErrors.dat index f4e53a5c9..7504fb240 100644 --- a/bin/Lng/Ukr/SyntaxTreeVisitorsErrors.dat +++ b/bin/Lng/Ukr/SyntaxTreeVisitorsErrors.dat @@ -12,6 +12,7 @@ FUNCTIONS_WITH_YIELDS_CANNOT_CONTAIN_NESTED_SUBROUTINES=Функції з yield FUNCTIONS_WITH_YIELDS_CANNOT_CONTAIN_LOCAL_TYPE_DEFINITIONS=Функції з yield не можуть містити локальні визначення типів YIELDS_INSIDE_WITH_ARE_ILLEGAL=Оператор yield заборонений всередині with LAMBDA_EXPRESSIONS_CANNOT_CONTAIN_YIELD=Лямбда-вирази не можуть містити yield +EMBEDDED_STATEMENT_CANNOT_BE_A_DECLARATION=Вложенная инструкция не может быть объявлением, используйте операторные скобки Var_{0}_is_already_defined=Змінна {0} уже визначена