// Copyright (c) Ivan Bondarev, Stanislav Mihalkovich (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.Collections.Generic; namespace PascalABCCompiler.TreeRealization { public enum function_compare { non_comparable, less, greater }; public class function_intersection_node { private function_node _left; private function_node _right; private function_compare _function_relation; public function_compare function_relation { get { return _function_relation; } set { _function_relation = value; } } public function_node left { get { return _left; } } public function_node right { get { return _right; } } public function_intersection_node(function_node left, function_node right) { _left = left; _right = right; } } /// /// Делегат, который вызывается при создании узла вызова метода. Если результат не null, то вместо узла вызова метода в дерево попадает возвращаемое этим длегатом значение. Таким образом он позволяет вычислять значения функции во время компиляции. /// /// Место вызова метода. /// Список параметровю /// Если значение функции с этими параметрами может быть вычислено во время компиляции. null иначе. public delegate expression_node compile_time_executor(location call_location,params expression_node[] parameters); /// /// Базовый класс для описания функций. /// [Serializable] public abstract class function_node : definition_node, SemanticTree.IFunctionNode { public override string ToString() { System.Text.StringBuilder str = new System.Text.StringBuilder(); str.Append((return_value_type != null ? "function " : "procedure ") + name + "("); foreach (var par in parameters) str.Append(par.ToString() + ";"); str.Append(")"); if (return_value_type != null) str.Append(": " + return_value_type); return str.ToString(); } private parameter_list _parameters = new parameter_list(); private type_node _ret_type; private compile_time_executor _compile_time_executor; private bool _is_operator = false; public bool IsOperator { get { return _is_operator; } set { _is_operator = value; } } private System.Collections.Generic.Dictionary _func_intersections = new System.Collections.Generic.Dictionary(); private void add_intersection(function_node _func,function_intersection_node _func_intersec) { _func_intersections.Add(_func, _func_intersec); } private function_intersection_node get_intersecion(function_node _func) { function_intersection_node _fint = null; bool ret = _func_intersections.TryGetValue(_func, out _fint); if (!ret) { return null; } return _fint; } public virtual bool is_extension_method { get { return false; } } public virtual SemanticTree.polymorphic_state polymorphic_state { get { return PascalABCCompiler.SemanticTree.polymorphic_state.ps_common; } set { } } public virtual SemanticTree.field_access_level field_access_level { get { return SemanticTree.field_access_level.fal_public; } set { } } public virtual bool is_generic_function { get { return false; } } public virtual function_node original_function { get { return null; } } public virtual bool is_generic_function_instance { get { return false; } } public virtual int num_of_default_parameters { get { return 0; } } //ограничения на generic-параметры public virtual List parameters_eliminations { get { return null; } } public virtual List get_generic_params_list() { return null; } public virtual bool is_final { get { return false; } set { } } public virtual int generic_parameters_count { get { return 0; } } public static void add_function_intersection(function_node left, function_node right, function_intersection_node intersec) { #if DEBUG function_intersection_node func_int_left = left.get_intersecion(right); if (func_int_left != null) { throw new TreeConverter.CompilerInternalError("Duplicate function intersection"); } #endif left.add_intersection(right, intersec); } public static function_intersection_node get_function_intersection(function_node left, function_node right) { return left.get_intersecion(right); } public static function_compare compare_functions(function_node left,function_node right) { function_intersection_node func_int_left = left.get_intersecion(right); function_intersection_node func_int_right = right.get_intersecion(left); if ((func_int_left == null) && (func_int_right == null)) { return function_compare.non_comparable; } if ((func_int_left != null) && (func_int_right == null)) { return func_int_left.function_relation; } if ((func_int_left == null) && (func_int_right != null)) { if (func_int_right.function_relation == function_compare.non_comparable) { return function_compare.non_comparable; } if (func_int_right.function_relation == function_compare.greater) { return function_compare.less; } if (func_int_right.function_relation == function_compare.less) { return function_compare.greater; } } if ((func_int_left != null) && (func_int_right != null)) { if ((func_int_left.function_relation == function_compare.less) && (func_int_right.function_relation == function_compare.greater)) { return function_compare.less; } if ((func_int_left.function_relation == function_compare.greater) && (func_int_right.function_relation == function_compare.less)) { return function_compare.greater; } throw new TreeConverter.CompilerInternalError("Contradiction in function relations"); } throw new TreeConverter.CompilerInternalError("Error in function relations"); } /// /// Делегат, который вызывается при создании узла вызова метода. Если результат не null, то вместо узла вызова метода в дерево попадает возвращаемое этим длегатом значение. Таким образом он позволяет вычислять значения функции во время компиляции. /// public compile_time_executor compile_time_executor { get { return _compile_time_executor; } set { _compile_time_executor = value; } } public virtual function_node get_instance(List param_types, bool stop_on_error, location loc) { return null; } public function_node() { } /// /// Конструктор узла. /// /// Тип возвращаемого значения функции. public function_node(type_node ret_type) { _ret_type=ret_type; } /* public function_node(parameter_list parameters,type_node ret_type) { _ret_type = ret_type; _parameters.AddRange(parameters); } */ /// /// Вид узла - базовый (basic), обычный (common) или экспортируемый (compiled). /// public abstract SemanticTree.node_kind node_kind { get; } /// /// Список формальных параметров функции. /// public parameter_list parameters { get { return _parameters; } } /// /// Тип возвращаемого значения функции. /// public type_node return_value_type { get { return _ret_type; } set { _ret_type = value; } } /// /// Имя функции. /// public abstract string name { get; } //TODO: Может is_overload оставить только в информации связанной с common_function_node. /* public abstract bool is_overload { get; } */ /// /// Расположение узла - в пространстве имен, классе или функции. /// public abstract SemanticTree.node_location_kind node_location_kind { get; } /// /// Обобщенный тип узла. /// public override general_node_type general_node_type { get { return general_node_type.function_node; } } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } /// /// Тип возвращаеого значения. /// SemanticTree.ITypeNode SemanticTree.IFunctionNode.return_value_type { get { return _ret_type; } } /// /// Список формальных параметров функции. /// SemanticTree.IParameterNode[] SemanticTree.IFunctionNode.parameters { get { return (_parameters.ToArray()); } } } [Serializable] public class convert_types_function_node : function_node { private bool _good = false; public convert_types_function_node(compile_time_executor ctn, bool good) { compile_time_executor = ctn; this._good = good; } public override SemanticTree.node_kind node_kind { get { return SemanticTree.node_kind.basic; } } public override string name { get { return ("$InternalName"); } } public override SemanticTree.node_location_kind node_location_kind { get { return SemanticTree.node_location_kind.in_namespace_location; } } public override semantic_node_type semantic_node_type { get { return semantic_node_type.convert_types_function_node; } } public bool Good { get { return _good; } } } public enum special_operation_kind { none, assign }; /// /// Класс, базовый, нигде не определенный метод, например операцию сложения двух целых чисел. /// [Serializable] public class basic_function_node : function_node, SemanticTree.IBasicFunctionNode { private string _name = null; private SemanticTree.basic_function_type _basic_function_type; private bool _overload; private special_operation_kind _operation_kind = special_operation_kind.none; /// /// Конструктор узла. /// /// Тип базовой функции. /// Тип возвращаемого значения. /// Перегружена-ли функция. public basic_function_node(SemanticTree.basic_function_type bft,type_node ret_type, bool is_overload) : base(ret_type) { _basic_function_type=bft; _overload = is_overload; } /// /// Конструктор узла. /// /// Тип базовой функции. /// Тип возвращаемого значения. /// Перегружена-ли функция. /// Имя public basic_function_node(SemanticTree.basic_function_type bft, type_node ret_type, bool is_overload, string name) : base(ret_type) { _basic_function_type = bft; _overload = is_overload; _name = name; } /// /// Какая именно это базовая функция. /// public SemanticTree.basic_function_type basic_function_type { get { return _basic_function_type; } } public special_operation_kind operation_kind { get { return _operation_kind; } set { _operation_kind = value; } } /// /// Имя функции. /// public override string name { get { if (_name != null) return _name; return _basic_function_type.ToString(); } } //TODO: Нужно ли is_overload для basic_function_node? public bool is_overload { get { return _overload; } /* set { _overload = value; } */ } /// /// Расположение узла - в пространстве имен, классе или функции. /// public override SemanticTree.node_location_kind node_location_kind { get { return SemanticTree.node_location_kind.in_namespace_location; } } /// /// Вид узла - обычный, базовый или откомпилированный. /// public override SemanticTree.node_kind node_kind { get { return SemanticTree.node_kind.basic; } } /// /// Тип узла. /// public override semantic_node_type semantic_node_type { get { return semantic_node_type.basic_function_node; } } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } } /// /// Обычная, определенная пользователем функция. /// [Serializable] public abstract class common_function_node : function_node, SemanticTree.ICommonFunctionNode { protected string _name; protected readonly local_variable_list _var_defs = new local_variable_list(); protected readonly List _label_defs = new List(); protected readonly function_constant_definition_list _const_defs = new function_constant_definition_list(); protected SemanticTree.SpecialFunctionKind specialFunctionKind = SemanticTree.SpecialFunctionKind.None; public SemanticTree.SpecialFunctionKind SpecialFunctionKind { get { return specialFunctionKind; } set { specialFunctionKind = value; } } //TODO: Возможно вынести в ассоциированную с функцией информацию. //Только указание - какая переменная возвращается. Ссылка на эту-же переменную есть в _var_defs. private local_variable _return_variable; private readonly common_in_function_function_node_list _fnl = new common_in_function_function_node_list(); private statement_node _function_code; //TODO: Возможно вынести оба этих поля в ассоциированную с функцией информацию. private bool _overload = false; private bool _is_forward = false; //TODO: Вынести в ассоциированную с функцией информацию. private statement_node_stack _cycles_stack = new statement_node_stack(); private SymbolTable.Scope _scope; private location _loc; //TODO: Возможно вынести оба этих поля в ассоциированную с функцией информацию. private int _num_of_default_variables; private int _num_of_for_cycles; protected List _generic_params = null; public List generic_params { get { return _generic_params; } set { _generic_params = value; } } public override List get_generic_params_list() { if (_generic_params == null) { return null; } List rez = new List(_generic_params.Count); foreach (type_node t in _generic_params) { rez.Add(t); } return rez; } public override int generic_parameters_count { get { if (_generic_params == null) { return 0; } return _generic_params.Count; } } public override bool is_generic_function { get { return _generic_params != null; } } private List _parameters_eliminations = null; public override List parameters_eliminations { get { if (_parameters_eliminations != null) { return _parameters_eliminations; } if (!this.is_generic_function) { throw new TreeConverter.CompilerInternalError("Function is not generic."); } _parameters_eliminations = generic_parameter_eliminations.make_eliminations_common(generic_params); return _parameters_eliminations; } } /// /// Конструктор узла. /// /// Имя функции. /// Расположение функции. /// Пространство имен этой функции. public common_function_node(string name, location loc,SymbolTable.Scope scope) { _name = name; _loc = loc; _scope = scope; } /// /// Конструктор узла. /// /// Имя функции. /// Тип возвращаемого значения функции. /// Расположение функции. /// Пространство имен этой функции. public common_function_node(string name,type_node ret_type,location loc, SymbolTable.Scope scope) : base(ret_type) { _name=name; _loc = loc; _scope = scope; } /// /// Число циклов for в функции. Временно хранится здесь. Будет удалено. /// public int num_of_for_cycles { get { return _num_of_for_cycles; } set { _num_of_for_cycles = value; } } /* public int inc_num_of_for_cycles() { _num_of_for_cycles++; } */ /// /// Стек циклов. Временно хранится здесь. Будет удален. Используется для реализации break и continue. /// public statement_node_stack cycles_stack { get { return _cycles_stack; } } /// /// Является ли это предописанием функции. Скорее всего будет удалено. /// public bool is_forward { get { return _is_forward; } set { _is_forward=value; } } /// /// Список констант определенных в функции. /// public function_constant_definition_list constants { get { return _const_defs; } } /// /// Поиск символа в функции. Осуществляет поиск и в объемлющих пространствах имен. /// /// Имя символа. /// Информация о найленном символе. null, если ни чего не найдено. public List find(string name, SymbolTable.Scope CurrentScope) { return _scope.Find(name, CurrentScope); } /// /// Поиск символа в функции. Осуществляет поиск только в пространстве имен функции. Используется для обнаружения повторного определения символа в пространстве имен. /// /// Имя символа. /// Информация о найленном символе. null, если ни чего не найдено. //public PascalABCCompiler.TreeConverter.SymbolInfo find_only_in_namespace(string name) //{ // return _scope.FindOnlyInScopeAndBlocks(name); //} /// /// Пространство имен функции. /// public SymbolTable.Scope scope { get { return _scope; } //TODO: Может хоть это закрыть. set { _scope=value; } } /// /// Число переменных, имеющих параметры по умолчанию. Возможно будет удалено. /// public int num_of_default_variables { get { return _num_of_default_variables; } set { _num_of_default_variables=value; } } /// /// Расположение имени функции в программе. /// public location loc { get { return _loc; } set { _loc = value; } } public override location location { get { return _loc; } } /// /// Расположение имени функции в программе. /// Используется при обходе дерева посетителем. /// public SemanticTree.ILocation Location { get { return _loc; } } /// /// Перегружена ли функция. Возможно будет удалено. /// public bool is_overload { get { return _overload; } set { _overload=value; } } /// /// Список переменных, определяемых в функции. /// public local_variable_list var_definition_nodes_list { get { return _var_defs; } } /// /// Список меток, определяемых в функции. /// public List label_nodes_list { get { return _label_defs; } } /// /// Список вложенных функций. /// public common_in_function_function_node_list functions_nodes_list { get { return _fnl; } } /// /// Код функции. /// public statement_node function_code { get { return _function_code; } set { _function_code = value; } } /// /// Имя функции. Для языков не чувствительных к регистру - в том виде, в котором функция определена. /// public override string name { get { return _name; } } public override int num_of_default_parameters { get { int num = 0; foreach (parameter p in parameters) { if (p.default_value != null) num++; } return num; } } public void SetName(string name) { _name = name; } /// /// Переменная, которая содержит возвращаемое значение функции. Скорее всего будет удалено. /// public local_variable return_variable { get { return _return_variable; } set { _return_variable=value; } } /// /// Вид узла - обычный, базовый или откомпилированный. /// public override SemanticTree.node_kind node_kind { get { return SemanticTree.node_kind.common; } } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } /// /// Код функции. /// Используется при обходе дерева посетителем. /// SemanticTree.IStatementNode SemanticTree.ICommonFunctionNode.function_code { get { return _function_code; } } /// /// Возвращаемая переменная функции. /// Используется при обходе дерева посетителем. /// Хотя не должно использоваться. Скорее всего будет удалено. /// SemanticTree.ILocalVariableNode SemanticTree.ICommonFunctionNode.return_variable { get { return _return_variable; } } /// /// Массив функций определенных в этой функции. /// Используется при обходе дерева посетителем. /// public SemanticTree.ICommonNestedInFunctionFunctionNode[] functions_nodes { get { return (_fnl.ToArray()); } } /// /// Массив переменных, определенных в функции. /// Используется при обходе дерева посетителем. /// public SemanticTree.ILocalVariableNode[] var_definition_nodes { get { return (_var_defs.ToArray()); } } /// /// Массив констант, определенных в функции. /// Используется при обходе дерева посетителем. /// SemanticTree.ICommonFunctionConstantDefinitionNode[] SemanticTree.ICommonFunctionNode.constants { get { return _const_defs.ToArray(); } } } /// /// Функция, определенная в пространстве имен. /// [Serializable] public class common_namespace_function_node : common_function_node, SemanticTree.ICommonNamespaceFunctionNode { private common_namespace_node _namespace; /// /// Конструктор узла. /// /// Имя функции. /// Расположение функции. /// Пространство имен, в котором определена функция. /// Пространство имен функции. public common_namespace_function_node(string name, location loc, common_namespace_node nsp,SymbolTable.Scope scope) : base(name, loc,scope) { _namespace = nsp; } /// /// Конструктор узла. /// /// Имя функции. /// Тип возвращааемого знчения функции. /// Расположение функции. /// Пространство имен, в котором определена функция. /// Пространство имен функции. public common_namespace_function_node(string name, type_node ret_type, location loc, common_namespace_node nsp, SymbolTable.Scope scope) : base(name,ret_type,loc,scope) { _namespace=nsp; } public type_node ConnectedToType = null; // frninja 20/05/16 private bool _is_yield_helper = false; public bool is_yield_helper { get { return _is_yield_helper; } set { _is_yield_helper = value; } } // end frninja public override bool is_extension_method { get { return ConnectedToType != null; } } SemanticTree.ITypeNode SemanticTree.ICommonNamespaceFunctionNode.ConnectedToType { get { return ConnectedToType; } } /// /// Пространство имен, в котором определена эта функция. /// public common_namespace_node namespace_node { get { return _namespace; } set { _namespace = value; } } /// /// Расположение функции - функция определена непосредственно в namespace. /// public override SemanticTree.node_location_kind node_location_kind { get { return SemanticTree.node_location_kind.in_namespace_location; } } /// /// Тип узла. /// public override semantic_node_type semantic_node_type { get { return semantic_node_type.common_namespace_function_node; } } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } /// /// Пространство имен в котором определена функция. /// Используется при обходе дерева посетителем. /// SemanticTree.ICommonNamespaceNode SemanticTree.ICommonNamespaceFunctionNode.namespace_node { get { return _namespace; } } /// /// Пространство имен в котором определена функция. /// Используется при обходе дерева посетителем. /// public SemanticTree.ICommonNamespaceNode comprehensive_namespace { get { return _namespace; } } public override function_node get_instance(List param_types, bool stop_on_error, location loc) { if (generic_parameters_count != param_types.Count) { if (stop_on_error) { throw new TreeConverter.SimpleSemanticError(loc, "FUNCTION_{0}_DEPEND_FROM_{1}_TYPE_PARAMS", name, this.generic_parameters_count); } return null; } int num; TreeConverter.CompilationErrorWithLocation err = generic_parameter_eliminations.check_type_list(param_types, parameters_eliminations, true, out num); if (err != null) { if (stop_on_error) { err.loc = loc; throw err; } return null; } return generic_convertions.get_function_instance(this, param_types); } } /// /// Функция, определенная в другой функции. /// [Serializable] public class common_in_function_function_node : common_function_node, SemanticTree.ICommonNestedInFunctionFunctionNode { private readonly common_function_node _up_function; /// /// Конструктор узла. /// /// Имя функции. /// Расположение имени функции в программе. /// Функция, в которой определена эта функция. /// Протсранство имен этой функции. public common_in_function_function_node(string name, location loc, common_function_node up_function, SymbolTable.Scope scope) : base(name, loc,scope) { _up_function = up_function; } /// /// Конструктор узла. /// /// Имя функции. /// Тип возвращаемого значения функции. /// Расположение имени функции в программе. /// Функция, в которой определена эта функция. /// Протсранство имен этой функции. public common_in_function_function_node(string name, type_node ret_type, location loc, common_function_node up_function, SymbolTable.Scope scope) : base(name,ret_type,loc,scope) { _up_function=up_function; } /// /// Функция, в которой определена эта функция. /// public common_function_node function { get { return _up_function; } } /// /// Расположение функции - функция определена в дргой функции. /// public override SemanticTree.node_location_kind node_location_kind { get { return SemanticTree.node_location_kind.in_function_location; } } /// /// Тип узла. /// public override semantic_node_type semantic_node_type { get { return semantic_node_type.common_in_function_function_node; } } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } /// /// Функция в которой определена эта функция. /// Используется при обходе дерева посетителем. /// SemanticTree.ICommonFunctionNode SemanticTree.IFunctionMemberNode.function { get { return _up_function; } } } /// /// Метод класса. /// [Serializable] public class common_method_node : common_function_node, SemanticTree.ICommonMethodNode { private common_type_node _cont_type; private SemanticTree.field_access_level _field_access_level; private SemanticTree.polymorphic_state _polymorphic_state; private type_node _explicit_interface; private bool _is_constructor; public bool first_statement = true; public bool inherited_ctor_called = false; public bool name_case_fixed = false; private bool _is_final = false; public type_node explicit_interface { get { return _explicit_interface; } set { _explicit_interface = value; } } public bool IsStatic { get { return _polymorphic_state == PascalABCCompiler.SemanticTree.polymorphic_state.ps_static; } } // frninja 20/05/16 private bool _is_yield_helper = false; public bool is_yield_helper { get { return _is_yield_helper; } set { _is_yield_helper = value; } } // end frninja public override bool is_final { get { return _is_final; } set { _is_final = value; } } private bool _newslot_awaited = false; public virtual bool newslot_awaited { get { return _newslot_awaited; } set { _newslot_awaited = value; } } //\ssyy private function_node _overrided_method; /// /// Конструктор узла. /// /// Имя функции. /// Расположение имени метода в программе. /// Тип, который содержит этот метод. /// Обычный, виртуальный или статический метод. /// Уровень доступа к методу. /// Пространство имен функции. public common_method_node(string name, location loc, common_type_node cont_type, SemanticTree.polymorphic_state polymorphic_state, SemanticTree.field_access_level field_access_level, SymbolTable.Scope scope) : base(name, loc,scope) { _cont_type = cont_type; _field_access_level = field_access_level; _polymorphic_state = polymorphic_state; } /// /// Конструктор узла. /// /// Имя функции. /// /// Расположение имени метода в программе. /// Тип, который содержит этот метод. /// Обычный, виртуальный или статический метод. /// Уровень доступа к методу. /// Пространство имен функции. public common_method_node(string name,type_node ret_type, location loc, common_type_node cont_type, SemanticTree.polymorphic_state polymorphic_state, SemanticTree.field_access_level field_access_level, SymbolTable.Scope scope) : base(name,ret_type,loc,scope) { _cont_type=cont_type; _field_access_level = field_access_level; _polymorphic_state = polymorphic_state; } public common_method_node(string name,location loc,SymbolTable.Scope scope) : base(name,loc,scope) { } /// /// Тип, который содержит этот метод. /// public common_type_node cont_type { get { return _cont_type; } set { _cont_type = value; } } public function_node overrided_method { get { return _overrided_method; } set { _overrided_method = value; } } private bool _is_reintroduce = false; /// /// Не ипольззутеся для генерации кода. информативная. /// public bool IsReintroduce { get { return _is_reintroduce; } set { _is_reintroduce = value; } } private local_variable _self_variable; public local_variable self_variable { get { return _self_variable; } set { _self_variable = value; } } //ssyy- /* /// /// Если данный метод определен в программе с ключевым словом constructor то это поле указывает на метод, соответствующий данному методу. См. компиляцию кода для конструкторов pascal. /// Возможно следует переместить это поле в ассоциированную с методом информацию. /// public common_method_node pascal_associated_constructor { get { return _pascal_associated_constructor; } set { _pascal_associated_constructor=value; } } */ /// /// Обычный, виртуальный или статический метод. /// public override SemanticTree.polymorphic_state polymorphic_state { get { return _polymorphic_state; } set { _polymorphic_state = value; } } /// /// Уровень доступа к методу. /// public override SemanticTree.field_access_level field_access_level { get { return _field_access_level; } //ssyy set { _field_access_level = value; } //\ssyy } public void set_access_level(SemanticTree.field_access_level fal) { _field_access_level = fal; } /// /// Является ли этот метод конструктором. /// public bool is_constructor { get { return _is_constructor; } set { _is_constructor=value; } } /// /// Расположение функции - функция определена в классе. /// public override SemanticTree.node_location_kind node_location_kind { get { return SemanticTree.node_location_kind.in_class_location; } } /// /// Тип узла. /// public override semantic_node_type semantic_node_type { get { return semantic_node_type.common_method_node; } } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } /// /// Тип, который содержит этот метод. /// public SemanticTree.ICommonTypeNode common_comprehensive_type { get { return _cont_type; } } /// /// Тип, который содержит этот метод. /// public virtual SemanticTree.ITypeNode comperehensive_type { get { return _cont_type; } } SemanticTree.IFunctionNode SemanticTree.ICommonMethodNode.overrided_method { get { return _overrided_method; } } public override function_node get_instance(List param_types, bool stop_on_error, location loc) { if (generic_parameters_count != param_types.Count) { if (stop_on_error) { throw new TreeConverter.SimpleSemanticError(loc, "FUNCTION_{0}_DEPEND_FROM_{1}_TYPE_PARAMS", name, this.generic_parameters_count); } return null; } int num; TreeConverter.CompilationErrorWithLocation err = generic_parameter_eliminations.check_type_list(param_types, parameters_eliminations, true, out num); if (err != null) { if (stop_on_error) { err.loc = loc; throw err; } return null; } return generic_convertions.get_function_instance(this, param_types); } } /// /// Обертка для откомпилированного метода. /// [Serializable] public class compiled_function_node : function_node, SemanticTree.ICompiledMethodNode { public override string ToString() => _mi.ToString().Replace("System.Collections.Generic.", "").Replace("System.", "").Replace("`1", "").Replace("`2", ""); private readonly System.Reflection.MethodInfo _mi; private compiled_type_node _cont_type; private int _generic_params_count; private int _num_of_default_parameters; private bool _is_extension_method=false; private compiled_type_node connected_to_type; private List _generic_params; private System.Reflection.PropertyInfo getter_of_property; private static System.Collections.Generic.Dictionary compiled_methods = new System.Collections.Generic.Dictionary(); /// /// Конструктор узла. /// /// Оборачиваемый метод. private compiled_function_node(System.Reflection.MethodInfo mi) { _mi=mi; type_node ret_val=null; if (_mi.ReturnType!=null) { ret_val=compiled_type_node.get_type_node(mi.ReturnType); if (ret_val == SystemLibrary.SystemLibrary.void_type) { ret_val = null; } } System.Reflection.ParameterInfo[] pinf=mi.GetParameters(); parameter_list pal = new parameter_list(); //if (!(_mi.IsGenericMethod)) { int i = 1; foreach (System.Reflection.ParameterInfo pi in pinf) { Type t = null; type_node par_type = null; SemanticTree.parameter_type pt = SemanticTree.parameter_type.value; // if (pi.ParameterType.Name.EndsWith("&") == true) //(ssyy) Лучше так: if (pi.ParameterType.IsByRef) { //t = pi.ParameterType.Assembly.GetType(pi.ParameterType.FullName.Substring(0, pi.ParameterType.FullName.Length - 1)); //(ssyy) Лучше так: t = pi.ParameterType.GetElementType(); par_type = compiled_type_node.get_type_node(t); pt = SemanticTree.parameter_type.var; } else { if (pi.Position == 0) { par_type = compiled_type_node.get_type_node(pi.ParameterType); if (NetHelper.NetHelper.IsExtensionMethod(mi)) { connected_to_type = par_type as compiled_type_node; } } } string name = pi.Name; compiled_parameter crpar = new compiled_parameter(pi); crpar.SetParameterType(pt); pal.AddElement(crpar); if (pi.IsOptional && pi.DefaultValue != null) _num_of_default_parameters++; i++; } } //else if (_mi.IsGenericMethod) { _generic_params_count = mi.GetGenericArguments().Length; } _is_extension_method = NetHelper.NetHelper.IsExtensionMethod(mi); this.return_value_type=ret_val; this.parameters.AddRange(pal); if (mi.Name.StartsWith("get_")) foreach (System.Reflection.PropertyInfo pi in mi.DeclaringType.GetProperties()) { if (pi.GetGetMethod() == mi) { getter_of_property = pi; break; } } } /// /// Метод создания узла. Позволяет обеспичивать уникальность обертки для каждого метода. /// /// Оборачиваемый метод. /// Класс-обертка на метод. public static compiled_function_node get_compiled_method(System.Reflection.MethodInfo mi) { compiled_function_node cfn = null; if (compiled_methods.TryGetValue(mi, out cfn)) { return cfn; } cfn = new compiled_function_node(mi); compiled_methods[mi] = cfn; return cfn; } /// /// Откомпилированный метод. /// public System.Reflection.MethodInfo method_info { get { return _mi; } } public bool is_readonly { get { if (getter_of_property != null && getter_of_property.GetSetMethod() == null) return true; return false; } } public override bool is_extension_method { get { return _is_extension_method; } } bool SemanticTree.ICompiledMethodNode.is_extension { get { return is_extension_method; } } public compiled_type_node ConnectedToType { get { return connected_to_type; } } public override int num_of_default_parameters { get { return _num_of_default_parameters; } } /// /// Класс, содержащий функцию. /// public compiled_type_node cont_type { get { if (_cont_type!=null) { return _cont_type; } _cont_type=compiled_type_node.get_type_node(_mi.DeclaringType); return _cont_type; } } public bool IsFinal { get { return _mi.IsFinal; } } /// /// Имя функции. /// public override string name { get { return _mi.Name; } } /// /// Функция - метод кдасса. /// public override SemanticTree.node_location_kind node_location_kind { get { return SemanticTree.node_location_kind.in_class_location; } } /// /// Вид узла. /// public override semantic_node_type semantic_node_type { get { return semantic_node_type.compiled_function_node; } } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } /// /// Обычный, виртуальный или статический метод. /// public override SemanticTree.polymorphic_state polymorphic_state { get { if (_mi.IsAbstract) { return SemanticTree.polymorphic_state.ps_virtual_abstract; } if (_mi.IsStatic) { return SemanticTree.polymorphic_state.ps_static; } if (_mi.IsVirtual && !_mi.IsFinal) { return SemanticTree.polymorphic_state.ps_virtual; } return SemanticTree.polymorphic_state.ps_common; } } public bool IsSpecialName { get { return _mi.IsSpecialName; } } public override bool is_final { get { return _mi.IsFinal; } } //public override //Ограничения, налагаемые на параметры generic-типа private List _parameters_eliminations = null; public override List parameters_eliminations { get { if (_parameters_eliminations != null) { return _parameters_eliminations; } if (!_mi.IsGenericMethodDefinition) { throw new TreeConverter.CompilerInternalError("Method is not generic."); } _parameters_eliminations = generic_parameter_eliminations.make_eliminations_compiled(_mi.GetGenericArguments()); return _parameters_eliminations; } } public override List get_generic_params_list() { if (is_generic_function || is_generic_function_instance) { Type[] tp = _mi.GetGenericArguments(); List rez = new List(tp.Length); foreach (Type t in tp) { rez.Add(compiled_type_node.get_type_node(t)); } return rez; } return null; } /// /// Уровень доступа к методу. /// public override SemanticTree.field_access_level field_access_level { get { return NetHelper.NetHelper.get_access_level(_mi); } } /// /// Вид узла - откомпилированный метод. /// public override SemanticTree.node_kind node_kind { get { return SemanticTree.node_kind.compiled; } } /// /// Класс, содержащий этот метод. /// Используется при обходе дерева посетителем. /// public SemanticTree.ICompiledTypeNode comprehensive_type { get { return cont_type; } } /// /// Класс, содержащий этот метод. /// Используется при обходе дерева посетителем. /// public SemanticTree.ITypeNode comperehensive_type { get { return cont_type; } } public override bool is_generic_function { get { return (this != SystemLibrary.SystemLibrary.resize_func) && _mi.IsGenericMethodDefinition; } } public override function_node original_function { get { if (is_generic_function_instance) { return compiled_function_node.get_compiled_method(_mi.GetGenericMethodDefinition()); } return null; } } public override int generic_parameters_count { get { return _generic_params_count; } } public override bool is_generic_function_instance { get { return _mi.IsGenericMethod && !_mi.IsGenericMethodDefinition; } } public override function_node get_instance(List param_types, bool stop_on_error, location loc) { int count = param_types.Count; if (count != _generic_params_count) { if (stop_on_error) { throw new TreeConverter.SimpleSemanticError(loc, "FUNCTION_{0}_DEPEND_FROM_{1}_TYPE_PARAMS", name, _generic_params_count); } return null; } int num; TreeConverter.CompilationErrorWithLocation err = generic_parameter_eliminations.check_type_list(param_types, parameters_eliminations, true, out num); if (err != null) { if (stop_on_error) { err.loc = loc; throw err; } return null; } bool all_compiled = true; List ts = new List(count); int k = 0; while (k < count && all_compiled) { compiled_type_node compt = param_types[k] as compiled_type_node; if (compt == null) { all_compiled = false; } else { ts.Add(compt._compiled_type); } ++k; } if (all_compiled) { System.Reflection.MethodInfo rez_t = _mi.MakeGenericMethod(ts.ToArray()); compiled_function_node rez = compiled_function_node.get_compiled_method(rez_t); return rez; } return generic_convertions.get_function_instance(this, param_types); } } [Serializable] public class return_node : statement_node, SemanticTree.IReturnNode { private expression_node _return_expr; public return_node(expression_node return_expr,location loc) : base(loc) { _return_expr=return_expr; } public expression_node return_expr { get { return _return_expr; } } public override semantic_node_type semantic_node_type { get { return semantic_node_type.return_node; } } public SemanticTree.IExpressionNode return_value { get { return _return_expr; } } public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } } /* //ssyy [Serializable] public class ctor_return_node : statement_node, SemanticTree.ICtorReturnNode { public ctor_return_node(location loc) : base(loc) { } public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit((SemanticTree.ICtorReturnNode)this); } public override semantic_node_type semantic_node_type { get { return semantic_node_type.ctor_return_node; } } } //\ssyy*/ //TODO: Связать с compiled_function_node. [Serializable] public class compiled_constructor_node : function_node, SemanticTree.ICompiledConstructorNode { private static System.Collections.Generic.Dictionary compiled_constructors = new System.Collections.Generic.Dictionary(); private int _num_of_default_parameters; private System.Reflection.ConstructorInfo _con_info; public static compiled_constructor_node get_compiled_constructor(System.Reflection.ConstructorInfo ci) { compiled_constructor_node ccn = null; if (compiled_constructors.TryGetValue(ci, out ccn)) { return ccn; } ccn = new compiled_constructor_node(ci); //compiled_constructors[ci] = ccn; return ccn; } //TODO: Возможно объеденить с compiled_function_node private compiled_constructor_node(System.Reflection.ConstructorInfo con_info) { _con_info=con_info; compiled_constructors[con_info] = this; //type_node ret_val=null; System.Reflection.ParameterInfo[] pinf=_con_info.GetParameters(); parameter_list pal=new parameter_list(); foreach(System.Reflection.ParameterInfo pi in pinf) { Type t=null; type_node par_type=null; SemanticTree.parameter_type pt=SemanticTree.parameter_type.value; if (pi.ParameterType.IsByRef) { t=pi.ParameterType.GetElementType(); par_type=compiled_type_node.get_type_node(t); pt=SemanticTree.parameter_type.var; } else { par_type=compiled_type_node.get_type_node(pi.ParameterType); } string name=pi.Name; compiled_parameter crpar=new compiled_parameter(pi); crpar.SetParameterType(pt); pal.AddElement(crpar); if (pi.IsOptional && pi.DefaultValue != null) _num_of_default_parameters++; } this.return_value_type=compiled_type_node.get_type_node(_con_info.DeclaringType); this.parameters.AddRange(pal); } /* public override bool is_overload { get { return false; } } */ public override string name { get { return _con_info.Name; } } public compiled_type_node compiled_type { get { return compiled_type_node.get_type_node(_con_info.DeclaringType); } } public override SemanticTree.node_kind node_kind { get { return SemanticTree.node_kind.compiled; } } public override SemanticTree.node_location_kind node_location_kind { get { return SemanticTree.node_location_kind.in_class_location; } } public override int num_of_default_parameters { get { return _num_of_default_parameters; } } public override semantic_node_type semantic_node_type { get { return semantic_node_type.compiled_constructor_node; } } public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } public System.Reflection.ConstructorInfo constructor_info { get { return _con_info; } } public SemanticTree.ICompiledTypeNode comprehensive_type { get { return compiled_type_node.get_type_node(_con_info.DeclaringType); } } public SemanticTree.ITypeNode comperehensive_type { get { return compiled_type_node.get_type_node(_con_info.DeclaringType); } } public override SemanticTree.field_access_level field_access_level { get { if (_con_info.IsPublic) { return SemanticTree.field_access_level.fal_public; } if (_con_info.IsPrivate) { return SemanticTree.field_access_level.fal_private; } //Как в System.Reflection отображается то, что метод protected? return SemanticTree.field_access_level.fal_protected; } } public SemanticTree.polymorphic_state polymorphic_state { get { return SemanticTree.polymorphic_state.ps_common; } } } [Serializable] public class function_lambda_node : expression_node, SemanticTree.ILambdaFunctionNode { private parameter_list _parameters = new parameter_list(); private type_node _ret_type; private statement_node _body; private function_node _function; //private compile_time_executor _compile_time_executor; //private bool _is_operator = false; /*public bool IsOperator { get { return _is_operator; } set { _is_operator = value; } }*/ /*private System.Collections.Generic.Dictionary _func_intersections = new System.Collections.Generic.Dictionary();*/ /*private void add_intersection(function_lambda_node _func, function_intersection_node _func_intersec) { _func_intersections.Add(_func, _func_intersec); }*/ /*private function_intersection_node get_intersecion(function_lambda_node _func) { function_intersection_node _fint = null; bool ret = _func_intersections.TryGetValue(_func, out _fint); if (!ret) { return null; } return _fint; }*/ /*public virtual SemanticTree.polymorphic_state polymorphic_state { get { return PascalABCCompiler.SemanticTree.polymorphic_state.ps_common; } set { } }*/ /*public virtual SemanticTree.field_access_level field_access_level { get { return SemanticTree.field_access_level.fal_public; } set { } }*/ public virtual bool is_generic_function { get { return false; } } /*public virtual function_lambda_node original_function { get { return null; } }*/ /*public virtual bool is_generic_function_instance { get { return false; } }*/ //ограничения на generic-параметры /*public virtual List parameters_eliminations { get { return null; } }*/ /*public virtual List get_generic_params_list() { return null; }*/ /*public virtual bool is_final { get { return false; } set { } }*/ public virtual int generic_parameters_count { get { return 0; } } /*public static void add_function_intersection(function_lambda_node left, function_lambda_node right, function_intersection_node intersec) { #if DEBUG function_intersection_node func_int_left = left.get_intersecion(right); if (func_int_left != null) { throw new TreeConverter.CompilerInternalError("Duplicate function intersection"); } #endif left.add_intersection(right, intersec); }*/ /*public static function_intersection_node get_function_intersection(function_lambda_node left, function_lambda_node right) { return left.get_intersecion(right); }*/ /*public static function_compare compare_functions(function_lambda_node left, function_lambda_node right) { function_intersection_node func_int_left = left.get_intersecion(right); function_intersection_node func_int_right = right.get_intersecion(left); if ((func_int_left == null) && (func_int_right == null)) { return function_compare.non_comparable; } if ((func_int_left != null) && (func_int_right == null)) { return func_int_left.function_relation; } if ((func_int_left == null) && (func_int_right != null)) { if (func_int_right.function_relation == function_compare.non_comparable) { return function_compare.non_comparable; } if (func_int_right.function_relation == function_compare.greater) { return function_compare.less; } if (func_int_right.function_relation == function_compare.less) { return function_compare.greater; } } if ((func_int_left != null) && (func_int_right != null)) { if ((func_int_left.function_relation == function_compare.less) && (func_int_right.function_relation == function_compare.greater)) { return function_compare.less; } if ((func_int_left.function_relation == function_compare.greater) && (func_int_right.function_relation == function_compare.less)) { return function_compare.greater; } throw new TreeConverter.CompilerInternalError("Contradiction in function relations"); } throw new TreeConverter.CompilerInternalError("Error in function relations"); }*/ /// /// Делегат, который вызывается при создании узла вызова метода. Если результат не null, то вместо узла вызова метода в дерево попадает возвращаемое этим длегатом значение. Таким образом он позволяет вычислять значения функции во время компиляции. /// /*public compile_time_executor compile_time_executor { get { return _compile_time_executor; } set { _compile_time_executor = value; } }*/ /*public virtual function_lambda_node get_instance(List param_types, bool stop_on_error, location loc) { return null; }*/ public function_lambda_node() { } public function_lambda_node(type_node ret_type) { _ret_type = ret_type; } /// /// Конструктор узла. /// /// Тип возвращаемого значения функции. public function_lambda_node(parameter_list parameters, type_node ret_type, statement_node body) { _parameters = parameters; _ret_type = ret_type; _body = body; } /* public function_node(parameter_list parameters,type_node ret_type) { _ret_type = ret_type; _parameters.AddRange(parameters); } */ /// /// Вид узла - базовый (basic), обычный (common) или экспортируемый (compiled). /// public SemanticTree.node_kind node_kind { get { return node_kind; } } /// /// Список формальных параметров функции. /// public parameter_list parameters { get { return _parameters; } } /// /// Тип возвращаемого значения функции. /// public type_node return_value_type { get { return _ret_type; } set { _ret_type = value; } } public function_node function { get { return _function; } set { _function = value; } } /// /// Имя функции. /// /*public string name { get { return name; } }*/ //TODO: Может is_overload оставить только в информации связанной с common_function_node. /* public abstract bool is_overload { get; } */ /// /// Расположение узла - в пространстве имен, классе или функции. /// public SemanticTree.node_location_kind node_location_kind { get { return node_location_kind; } } /// /// Обобщенный тип узла. /// public override general_node_type general_node_type { get { return general_node_type.function_node; } } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } /// /// Тип возвращаеого значения. /// SemanticTree.ITypeNode SemanticTree.ILambdaFunctionNode.return_value_type { get { return _ret_type; } } /// /// Список формальных параметров функции. /// SemanticTree.IParameterNode[] SemanticTree.ILambdaFunctionNode.parameters { get { return (_parameters.ToArray()); } } SemanticTree.IStatementNode SemanticTree.ILambdaFunctionNode.body { get { return _body; } } public override semantic_node_type semantic_node_type { get { return semantic_node_type.return_node; } } SemanticTree.IFunctionNode SemanticTree.ILambdaFunctionNode.function { get { return _function; } } } [Serializable] public class function_lambda_call_node : expression_node, SemanticTree.ILambdaFunctionCallNode { private expressions_list _parameters = new expressions_list(); private function_lambda_node _fln; public function_lambda_call_node() { } /*public function_lambda_call_node(type_node ret_type) { _ret_type = ret_type; }*/ /// /// Конструктор узла. /// /// Тип возвращаемого значения функции. public function_lambda_call_node(expressions_list parameters, function_lambda_node fln) { _parameters = parameters; _fln = fln; } public expressions_list parameters { get { return _parameters; } } public SemanticTree.node_kind node_kind { get { return node_kind; } } public function_lambda_node fln { get { return _fln; } } public SemanticTree.node_location_kind node_location_kind { get { return node_location_kind; } } /// /// Обобщенный тип узла. /// public override general_node_type general_node_type { get { return general_node_type.function_node; } } /// /// Метод для обхода дерева посетителем. /// /// Класс - посетитель дерева. public override semantic_node_type semantic_node_type { get { return semantic_node_type.return_node; } } SemanticTree.IExpressionNode[] SemanticTree.ILambdaFunctionCallNode.parameters { get { return (_parameters.ToArray()); } } SemanticTree.ILambdaFunctionNode SemanticTree.ILambdaFunctionCallNode.lambda { get { return fln; } } public override void visit(SemanticTree.ISemanticVisitor visitor) { visitor.visit(this); } } }