// 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 PascalABCCompiler.Collections;
namespace PascalABCCompiler.TreeRealization
{
[Serializable]
public abstract class base_function_call : expression_node, SemanticTree.IFunctionCallNode
{
///
/// Список фактических параметров при вызове функции.
///
private readonly expressions_list _parametres = new expressions_list();
public base_function_call(type_node tn, location loc) : base(tn, loc)
{
}
private bool _isExplicitConversion = false;
public bool IsExplicitConversion
{
get
{
return _isExplicitConversion;
}
set
{
_isExplicitConversion = value;
}
}
public virtual base_function_call copy()
{
return this;
}
///
/// Список фактических параметров. Количество и типы формальных и фактических параметров сверяется
/// на этапе построения семантического дерева. При необходимости при построении семантического дерева
/// вставляются узлы преобразования типов.
///
public expressions_list parameters
{
get
{
return _parametres;
}
}
///
/// Массив с параметрами функции.
/// Используется при обходе дерева посетителем.
///
public SemanticTree.IExpressionNode[] real_parameters
{
get
{
return (_parametres.ToArray());
}
}
public abstract function_node simple_function_node
{
get;
}
///
/// Вызываемая функция.
/// Используется при обходе дерева посетителем.
///
public SemanticTree.IFunctionNode function
{
get
{
return simple_function_node;
}
}
private type_node _ret_type = null;
public type_node ret_type
{
get
{
if (_ret_type == null)
return simple_function_node.return_value_type;
return _ret_type;
}
set
{
_ret_type = value;
}
}
public override type_node type
{
get
{
if (_ret_type == null)
{
return base.type;
}
return ret_type;
}
}
//ssyy
public virtual bool last_result_function_call
{
get
{
return false;
}
set
{
}
}
//\ssyy
}
///
/// Базовый класс, для представления вызовов функций.
///
/// Тип узла функции, которую мы вызываем.
[Serializable]
public abstract class base_function_call_with_method : base_function_call
where FunctionNodeType : function_node
{
/*private type_node __type=null;
public virtual void SetType(type_node _type)
{
__type=__type;
}
public override type_node type
{
get
{
if (__type != null)
return __type;
return base.type;
}
}*/
///
/// Вызываемая функция.
///
private FunctionNodeType _function_node;
///
/// Конструктор узла.
///
/// Вызывамый метод.
public base_function_call_with_method(FunctionNodeType _function,location loc)
: base(_function.return_value_type,loc)
{
_function_node = _function;
}
///
/// Вызываемый метод.
///
public FunctionNodeType function_node
{
get
{
return _function_node;
}
}
public override function_node simple_function_node
{
get
{
return _function_node;
}
}
}
///
/// Класс, представляющий вызов базового метода.
///
[Serializable]
public class basic_function_call : base_function_call_with_method, SemanticTree.IBasicFunctionCallNode
{
///
/// Конструктор узла.
///
/// Ссылка на функцию, которую мы вызываем.
public basic_function_call(basic_function_node basic_func,location loc)
: base(basic_func,loc)
{
}
public basic_function_call(basic_function_node basic_func,location loc, params expression_node[] prms)
: base(basic_func,loc)
{
this.parameters.AddRange(prms);
}
///
/// Тип узла.
///
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type.basic_function_call;
}
}
///
/// Метод для обхода дерева посетителем.
///
/// Класс - посетитель дерева.
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit((SemanticTree.IBasicFunctionCallNode)this);
}
///
/// Вызываемый базовый метод.
/// Используется для обхода дерева посетителем.
///
SemanticTree.IBasicFunctionNode SemanticTree.IBasicFunctionCallNode.basic_function
{
get
{
return function_node;
}
}
}
///
/// Класс, представляющий вызов метода, расположенного в пространстве имен.
///
[Serializable]
public class common_namespace_function_call : base_function_call_with_method, SemanticTree.ICommonNamespaceFunctionCallNode
{
///
/// Конструктор узла.
///
/// Ссылка на функцию, которую мы вызываем.
public common_namespace_function_call(common_namespace_function_node namespace_func,location loc)
: base(namespace_func,loc)
{
if (namespace_func is generic_namespace_function_instance_node)
{
common_namespace_function_node cnfn = (namespace_func as generic_namespace_function_instance_node).original_function as common_namespace_function_node;
if (cnfn.function_code is wrapped_statement)
{
wrapped_statement ws = cnfn.function_code as wrapped_statement;
cnfn.function_code = new empty_statement(null);
cnfn.function_code = ws.restore();
}
}
else if (namespace_func.function_code is wrapped_statement)
{
wrapped_statement ws = namespace_func.function_code as wrapped_statement;
namespace_func.function_code = new empty_statement(null);
namespace_func.function_code = ws.restore();
}
}
///
/// Метод для обхода дерева посетителем.
///
/// Класс - посетитель дерева.
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit((SemanticTree.ICommonNamespaceFunctionCallNode)this);
}
///
/// Тип узла.
///
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type.common_namespace_function_call;
}
}
///
/// Вызываемый базовый метод.
/// Используется для обхода дерева посетителем.
///
SemanticTree.ICommonNamespaceFunctionNode SemanticTree.ICommonNamespaceFunctionCallNode.namespace_function
{
get
{
return function_node;
}
}
public override base_function_call copy()
{
common_namespace_function_call cnfc_copy = new common_namespace_function_call(this.function_node, this.location);
cnfc_copy.parameters.AddRange(this.parameters);
return cnfc_copy;
}
}
///
/// Класс, представляющий вызов метода, вложенного в другой метод.
///
[Serializable]
public class common_in_function_function_call : base_function_call_with_method,
SemanticTree.ICommonNestedInFunctionFunctionCallNode
{
///
/// Разность между статической глубиной вызываемого метода и статической глубиной вызывающего метода.
///
private int _static_depth;
///
/// Конструктор узла.
///
/// Вызываемый метод.
/// Разность между статической глубиной вызываемого метода и статической глубиной вызывающего метода.
public common_in_function_function_call(common_in_function_function_node common_func, int static_depth,location loc)
:base(common_func,loc)
{
_static_depth = static_depth;
}
///
/// Статическая глубина вложенной функции.
///
public int static_depth
{
get
{
return _static_depth;
}
}
///
/// Тип узла.
///
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type.common_in_function_function_call;
}
}
///
/// Метод для обхода дерева посетителем.
///
/// Класс - посетитель дерева.
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit((SemanticTree.ICommonNestedInFunctionFunctionCallNode)this);
}
///
/// Вызываемый метод.
/// Используется при обходе дерева посетителем.
///
public SemanticTree.ICommonNestedInFunctionFunctionNode common_function
{
get
{
return function_node;
}
}
public override base_function_call copy()
{
common_in_function_function_call cffc_copy = new common_in_function_function_call(this.function_node, this.static_depth, this.location);
cffc_copy.parameters.AddRange(this.parameters);
return cffc_copy;
}
}
[Serializable]
public class common_method_call : base_function_call_with_method, SemanticTree.ICommonMethodCallNode
{
private expression_node _obj;
public common_method_call(common_method_node method, expression_node obj,location loc)
: base(method,loc)
{
_obj = obj;
_virtual_call = true;
}
//Экземпляр класса, данный метод которого нужно вызвать.
public expression_node obj
{
get
{
return _obj;
}
}
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type.common_method_call;
}
}
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit((SemanticTree.ICommonMethodCallNode)this);
}
SemanticTree.ICommonMethodNode SemanticTree.ICommonMethodCallNode.method
{
get
{
return function_node;
}
}
SemanticTree.IExpressionNode SemanticTree.ICommonMethodCallNode.obj
{
get
{
return _obj;
}
}
//ssyy
private bool _last_result_function_call;
public override bool last_result_function_call
{
get
{
return _last_result_function_call;
}
set
{
_last_result_function_call = value;
}
}
//\ssyy
bool _virtual_call;
public bool virtual_call
{
get
{
return _virtual_call;
}
set
{
_virtual_call = value;
}
}
public override base_function_call copy()
{
common_method_call cmc_copy = new common_method_call(this.function_node, this.obj, this.location);
cmc_copy.parameters.AddRange(this.parameters);
return cmc_copy;
}
}
[Serializable]
public class common_static_method_call : base_function_call_with_method, SemanticTree.ICommonStaticMethodCallNode
{
private common_type_node _common_type;
public common_static_method_call(common_method_node static_method,location loc) :
base(static_method,loc)
{
//_method = static_method;
_common_type = static_method.cont_type;
}
//Тип, статический метод которого вызываем.
public common_type_node common_type
{
get
{
return _common_type;
}
}
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type.common_static_method_call;
}
}
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit((SemanticTree.ICommonStaticMethodCallNode)this);
}
SemanticTree.ICommonTypeNode SemanticTree.ICommonStaticMethodCallNode.common_type
{
get
{
return _common_type;
}
}
SemanticTree.ICommonMethodNode SemanticTree.ICommonStaticMethodCallNode.static_method
{
get
{
return function_node;
}
}
public override base_function_call copy()
{
common_static_method_call cmc_copy = new common_static_method_call(this.function_node, this.location);
cmc_copy.parameters.AddRange(this.parameters);
return cmc_copy;
}
}
[Serializable]
public class common_constructor_call : common_static_method_call, SemanticTree.ICommonConstructorCall
{
public common_constructor_call(common_method_node constructor_node,location loc) :
base(constructor_node,loc)
{
}
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit((SemanticTree.ICommonConstructorCall)this);
}
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type.common_constructor_call;
}
}
//ssyy
//Станет ложью, если это вызов конструктора предка
public bool _new_obj_awaited = true;
public bool new_obj_awaited()
{
return _new_obj_awaited;
}
//\ssyy
}
[Serializable]
public class compiled_function_call : base_function_call_with_method, SemanticTree.ICompiledMethodCallNode
{
private expression_node _obj;
public compiled_function_call(compiled_function_node compiled_method, expression_node obj,location loc) :
base(compiled_method,loc)
{
_obj = obj;
}
//Экземпляр класса, данный метод которого нужно вызвать.
public expression_node obj
{
get
{
return _obj;
}
}
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type.compiled_function_call;
}
}
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit((SemanticTree.ICompiledMethodCallNode)this);
}
SemanticTree.IExpressionNode SemanticTree.ICompiledMethodCallNode.obj
{
get
{
return _obj;
}
}
SemanticTree.ICompiledMethodNode SemanticTree.ICompiledMethodCallNode.compiled_method
{
get
{
return function_node;
}
}
//ssyy
private bool _last_result_function_call;
public override bool last_result_function_call
{
get
{
return _last_result_function_call;
}
set
{
_last_result_function_call = value;
}
}
//\ssyy
bool _virtual_call = true;
public bool virtual_call
{
get
{
return _virtual_call;
}
set
{
_virtual_call = value;
}
}
public override base_function_call copy()
{
compiled_function_call cfc_copy = new compiled_function_call(this.function_node, this.obj, this.location);
cfc_copy.parameters.AddRange(this.parameters);
return cfc_copy;
}
}
//Внимательно простмореть реализацию.
//Обратить внимание на _compiled_type.
[Serializable]
public class compiled_static_method_call : base_function_call_with_method, SemanticTree.ICompiledStaticMethodCallNode
{
private compiled_type_node _compiled_type;
private type_node_list _template_parametres_list = new type_node_list();
public compiled_static_method_call(compiled_function_node static_method,location loc) :
base(static_method,loc)
{
_compiled_type = static_method.cont_type;
}
//Тип, статический метод которого мы вызываем.
public compiled_type_node compiled_type
{
get
{
return _compiled_type;
}
}
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type.compiled_static_method_call;
}
}
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit((SemanticTree.ICompiledStaticMethodCallNode)this);
}
public type_node_list template_parametres_list
{
get
{
return _template_parametres_list;
}
}
SemanticTree.ICompiledTypeNode SemanticTree.ICompiledStaticMethodCallNode.compiled_type
{
get
{
return _compiled_type;
}
}
SemanticTree.ICompiledMethodNode SemanticTree.ICompiledStaticMethodCallNode.static_method
{
get
{
return function_node;
}
}
public SemanticTree.ITypeNode[] template_parametres
{
get
{
return (_template_parametres_list.ToArray());
}
}
public override base_function_call copy()
{
compiled_static_method_call csmc_copy = new compiled_static_method_call(this.function_node, this.location);
csmc_copy.parameters.AddRange(this.parameters);
return csmc_copy;
}
}
[Serializable]
public class compiled_constructor_call : base_function_call_with_method, SemanticTree.ICompiledConstructorCall
{
public compiled_constructor_call(compiled_constructor_node _constructor,location loc) :
base(_constructor,loc)
{
}
public compiled_type_node compiled_type
{
get
{
return function_node.compiled_type;
}
}
public override void visit(SemanticTree.ISemanticVisitor visitor)
{
visitor.visit((SemanticTree.ICompiledConstructorCall)this);
}
public override semantic_node_type semantic_node_type
{
get
{
return semantic_node_type.compiled_constructor_call;
}
}
SemanticTree.ICompiledTypeNode SemanticTree.ICompiledConstructorCall.compiled_type
{
get
{
return function_node.comprehensive_type;
}
}
SemanticTree.ICompiledConstructorNode SemanticTree.ICompiledConstructorCall.constructor
{
get
{
return function_node;
}
}
//ssyy
//Станет ложью, если это вызов конструктора предка
public bool _new_obj_awaited = true;
public bool new_obj_awaited()
{
return _new_obj_awaited;
}
//\ssyy
}
}